Spring 当我启动应用程序时,使用 @around 的 AOP 抛出 org.springframework.beans.factory.BeanCreationException

Spring AOP using @around throws org.springframework.beans.factory.BeanCreationException when I start the application

我正在构建一个 Spring 引导 MVC 应用程序,它需要对某些控制器方法进行身份验证检查。为此,我没有使用 Spring 提供的任何身份管理框架,因为这是一个学校项目,我需要自己做。所以我计划将面向方面的编程与 Spring AOP 一起使用,并创建一个注解 AuthentificatedOnly,如下所示:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthentificatedOnly {

}

我还创建了一个应与此注释匹配的方面,如果用户未通过身份验证则抛出异常(使用我还创建的 UserManager,使用 Spring IOC 自动装配,并且自从我直接在一些控制器上测试过,所以问题不可能出在用户管理器上)。 方面看起来像这样:

@Aspect
@Component
public class AuthentificationCheckAspect {

    @Autowired
    private IUserManager userManager;

    @Around("@target(dgl.dgladmin_rest.model.auth.AuthentificatedOnly)")
    public Object checkAuthentification(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("checking authentification for " + joinPoint.getSignature().toShortString());

        if(!userManager.isConnected())throw new AuthentificationException();
        return joinPoint.proceed();
    }
}

我在一些控制器方法上使用了我的注释,这些方法 return 一个视图或一个 ModelAndView,如下所示:

@Controller
public class UserController{
[...]

@AuthentificatedOnly
    @GetMapping("/users")
    public String userPage(Model model){
        return "users";
    }

[...]
}

当我启动我的应用程序时,它抛出异常并停止:

  .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.6.RELEASE)

2018-11-08 16:43:31.193  INFO 4060 --- [  restartedMain] dgl.Application                          : Starting Application on WARREN-LAPTOP with PID 4060 (started by Warren in C:\Users\Warren\Documents\école\HELMOB3\Archi Log\projet\DGLAdmin_REST)
2018-11-08 16:43:31.199  INFO 4060 --- [  restartedMain] dgl.Application                          : No active profile set, falling back to default profiles: default
2018-11-08 16:43:31.681  INFO 4060 --- [  restartedMain] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@713bc672: startup date [Thu Nov 08 16:43:31 CET 2018]; root of context hierarchy
2018-11-08 16:43:35.317  INFO 4060 --- [  restartedMain] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'authentificationCheckAspect' with a different definition: replacing [Generic bean: class [dgl.dgladmin_rest.model.auth.AuthentificationCheckAspect]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [C:\Users\Warren\Documents\école\HELMOB3\Archi Log\projet\DGLAdmin_REST\target\classes\dgl\dgladmin_rest\model\auth\AuthentificationCheckAspect.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=application; factoryMethodName=authentificationCheckAspect; initMethodName=null; destroyMethodName=(inferred); defined in dgl.Application]
2018-11-08 16:43:36.956  INFO 4060 --- [  restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$cf3c81e] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-11-08 16:43:37.134  INFO 4060 --- [  restartedMain] o.s.aop.framework.CglibAopProxy          : Method [void org.springframework.transaction.annotation.AbstractTransactionManagementConfiguration.setConfigurers(java.util.Collection)] is package-visible across different ClassLoaders and cannot get proxied via CGLIB: Declare this method as public or protected if you need to support invocations through the proxy.
2018-11-08 16:43:37.274  INFO 4060 --- [  restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.hateoas.config.HateoasConfiguration' of type [org.springframework.hateoas.config.HateoasConfiguration$$EnhancerBySpringCGLIB$$bc741550] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-11-08 16:43:37.298  INFO 4060 --- [  restartedMain] o.s.aop.framework.CglibAopProxy          : Method [org.springframework.plugin.core.support.PluginRegistryFactoryBean org.springframework.hateoas.config.HateoasConfiguration.relProviderPluginRegistry()] is package-visible across different ClassLoaders and cannot get proxied via CGLIB: Declare this method as public or protected if you need to support invocations through the proxy.
2018-11-08 16:43:37.298  INFO 4060 --- [  restartedMain] o.s.aop.framework.CglibAopProxy          : Method [org.springframework.hateoas.core.AnnotationRelProvider org.springframework.hateoas.config.HateoasConfiguration.annotationRelProvider()] is package-visible across different ClassLoaders and cannot get proxied via CGLIB: Declare this method as public or protected if you need to support invocations through the proxy.
2018-11-08 16:43:37.298  INFO 4060 --- [  restartedMain] o.s.aop.framework.CglibAopProxy          : Method [org.springframework.hateoas.RelProvider org.springframework.hateoas.config.HateoasConfiguration.defaultRelProvider()] is package-visible across different ClassLoaders and cannot get proxied via CGLIB: Declare this method as public or protected if you need to support invocations through the proxy.
2018-11-08 16:43:37.299  INFO 4060 --- [  restartedMain] o.s.aop.framework.CglibAopProxy          : Method [org.springframework.hateoas.core.DelegatingRelProvider org.springframework.hateoas.config.HateoasConfiguration._relProvider(org.springframework.plugin.core.PluginRegistry)] is package-visible across different ClassLoaders and cannot get proxied via CGLIB: Declare this method as public or protected if you need to support invocations through the proxy.
2018-11-08 16:43:37.299  INFO 4060 --- [  restartedMain] o.s.aop.framework.CglibAopProxy          : Method [org.springframework.hateoas.LinkDiscoverers org.springframework.hateoas.config.HateoasConfiguration.linkDiscoverers(org.springframework.plugin.core.PluginRegistry)] is package-visible across different ClassLoaders and cannot get proxied via CGLIB: Declare this method as public or protected if you need to support invocations through the proxy.
2018-11-08 16:43:37.299  INFO 4060 --- [  restartedMain] o.s.aop.framework.CglibAopProxy          : Method [org.springframework.hateoas.config.ConverterRegisteringBeanPostProcessor org.springframework.hateoas.config.HateoasConfiguration.jackson2ModuleRegisteringBeanPostProcessor(org.springframework.beans.factory.ObjectFactory)] is package-visible across different ClassLoaders and cannot get proxied via CGLIB: Declare this method as public or protected if you need to support invocations through the proxy.
2018-11-08 16:43:37.313  WARN 4060 --- [  restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.hateoas.config.HateoasConfiguration': Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class org.springframework.hateoas.config.HateoasConfiguration$$EnhancerBySpringCGLIB$$bc741550: Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
2018-11-08 16:43:37.328  INFO 4060 --- [  restartedMain] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-11-08 16:43:37.346 ERROR 4060 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.hateoas.config.HateoasConfiguration': Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class org.springframework.hateoas.config.HateoasConfiguration$$EnhancerBySpringCGLIB$$bc741550: Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:581) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=15=](AbstractBeanFactory.java:317) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:373) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1246) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1096) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:535) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=15=](AbstractBeanFactory.java:317) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:236) ~[spring-context-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:708) ~[spring-context-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:533) ~[spring-context-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:386) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at dgl.Application.main(Application.java:34) [classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.0.6.RELEASE.jar:2.0.6.RELEASE]
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class org.springframework.hateoas.config.HateoasConfiguration$$EnhancerBySpringCGLIB$$bc741550: Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:208) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:473) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:355) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:304) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:431) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1698) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    ... 29 common frames omitted
Caused by: org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
    at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:345) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:492) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.apply(AbstractClassGenerator.java:93) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.apply(AbstractClassGenerator.java:91) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.cglib.core.internal.LoadingCache.call(LoadingCache.java:54) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_101]
    at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:116) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:291) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:480) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:337) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:58) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205) ~[spring-aop-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    ... 36 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
    at sun.reflect.GeneratedMethodAccessor44.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
    at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:459) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:336) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    ... 49 common frames omitted
Caused by: java.lang.IllegalAccessError: class org.springframework.hateoas.config.HateoasConfiguration$$EnhancerBySpringCGLIB$$a0484109 cannot access its superclass org.springframework.hateoas.config.HateoasConfiguration
    at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_101]
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_101]
    ... 54 common frames omitted

我认为问题出在我方面的@Around 注释中,因为如果我将@Around 注释替换为@Pointcut 注释,应用程序将正常启动,但随后我可以调用受影响的方法并且没有任何反应(甚至System.out.println 未达到,所以我相信该方面从未使用过)。

我找到了问题的解决方案: 使用

@Around("@annotation(dgl.dgladmin_rest.model.auth.AuthentificatedOnly)")

而不是

@Around("@target(dgl.dgladmin_rest.model.auth.AuthentificatedOnly)")