AspectJ + @Configurable

Jas*_*son 5 java aop spring dependency-injection aspectj

尝试使用AspectJ和@ConfigurableSpring应用程序.

  • 如果我@Component在类上加载带有注释的Spring ,则AspectJ包装器将工作并包装所有目标方法,并且@Autowired注释会导致注入依赖项.但是该类无法在运行时使用new关键字进行实例化,并且已注入依赖项.
  • 如果我加载@Configurable没有AspectJ bean 的类,则会正确注入所有依赖项,new但是没有一个方法通过AspectJ代理.

我怎么能两个都做?

这是我的代码.组态:

@Configuration
@ComponentScan(basePackages="com.example")
@EnableSpringConfigured
@EnableAspectJAutoProxy
@EnableLoadTimeWeaving
public class TestCoreConfig {

    @Bean
    public SecurityAspect generateSecurityAspect(){
        return new SecurityAspect();
    }


    @Bean
    public SampleSecuredClass createSampleClass(){
        return new SampleSecuredClass();
    }
}
Run Code Online (Sandbox Code Playgroud)

方面:

@Aspect
public class SecurityAspect {

    @Pointcut("execution(public * *(..))")
    public void publicMethod() {}


    @Around("publicMethod()")
    public boolean test (ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Here!");
        joinPoint.proceed();
        return true;    
    }

}
Run Code Online (Sandbox Code Playgroud)

SampleClass:

//@Configurable
@Component
public class SampleSecuredClass {

    @Autowired
    public SecurityService securityService;

    public boolean hasSecurityService(){
        return securityService != null;
    }

    public boolean returnFalse(){
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

单元测试:

@ContextConfiguration(classes={TestCoreConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class SecurityAspectComponentTest {

    @Autowired
    private SampleSecuredClass sampleSecuredClass;

    @Test
    public void testSecurityRoles(){
        //SampleSecuredClass sampleSecuredClass = new SampleSecuredClass();

        assertTrue("We need to ensure the the @Configurable annotation injected the services correctly", sampleSecuredClass.hasSecurityService());

        assertTrue("We need to ensure the the method has been overwritten", sampleSecuredClass.returnFalse());
    }

}
Run Code Online (Sandbox Code Playgroud)
  • 如果我删除了bean TestCoreConfigSampleSecuredClass在测试中创建了一个实例new,并将其注释更改为@Configurable然后注入了服务,但不应用该方面.
  • 如果我按原样运行(通过注入SampleSecuredClass作为bean),那么方面工作并注入服务,但是必须在框架启动时创建所有对象.我想使用@Configurable注释.
  • 如果我同时使用@Configurable注释和Aspect,那么我会收到illegal type in constant pool错误并且上下文不会启动.

其他信息.

  • 我尝试了一些不同的java代理 - 包括spring instrumentation和aspectjwrapper.没变.

  • 如果我包含aop.xml文件,那么方面可以工作但不能@Configurable.

Fil*_*lip 1

这似乎是等待发生的文档深入讨论之一:)

首先,我将启用调试日志记录,org.springframework因为这肯定会提供一些有意义的见解,了解 Spring 的作用和时间......

话虽这么说,我相信你的问题存在于spring 上下文生命周期的迷雾中,所以我会仔细查看文档,尤其是周围的文档

  1. 手动指定bean依赖于配置方面depends-on="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"

  2. ...或周围的注释@Configurable(preConstruction=true)

如果您希望在构造函数体执行之前注入依赖项

  1. ...或者@Configurable(autowire=Autowire.BY_NAME,dependencyCheck=true)

最后,您可以使用 dependencyCheck 属性为新创建和配置的对象中的对象引用启用 Spring 依赖项检查。

仔细阅读文档,看看这些命中是否适用以及如何适用,请让我们知道您找到的解决方案。它绝对应该是一本非常有趣的读物。