Spring AOP с использованием @around throws org.springframework.beans.factory.BeanCreationException при запуске приложения - PullRequest
0 голосов
/ 08 ноября 2018

Я создаю приложение Spring Boot 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();
    }
}

Я использую свою аннотацию для некоторых методов контроллера, которые возвращают представление или 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$$3cf3c81e] 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$0(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$0(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$3.apply(AbstractClassGenerator.java:93) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:91) ~[spring-core-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.cglib.core.internal.LoadingCache$2.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 не достигнут, поэтому я считаю, что этот аспект никогда не используется).

1 Ответ

0 голосов
/ 10 ноября 2018

Я нашел решение своей проблемы: Используйте

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

вместо

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