Spring5参考指南:AspectJ高级编程之Configurable

遇到的问题

前面的文章我们讲到了在Spring中使用Aspect。但是Aspect的都是Spring管理的Bean。 现在有一个问题,实际工作中,我们经常会想new一个Bean,然后在这个Bean中注入Spring管理的其他Bean。但是new出来的bean已经脱离Spring的管控了。

该怎么处理呢?

@Configurable

Spring提供了一个@Configurable的注解,可以实现这个功能,我们看一个例子:

@Configurable(autowire= Autowire.BY_NAME, preConstruction = true)
public class Account {

    private static Logger log= LoggerFactory.getLogger(Account.class);

    private String name;

    @Autowired
    private BeanA beanA;

    public  Account(){
        log.info("init Account");
    }

    public Object getBeanA() {
        return beanA;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

这里定义了一个Account类,它里面有依赖的BeanA,我们想在new Account()的时候, 直接使用Spring注入的BeanA。

preConstruction = true 表示依赖的Bean在构造函数调用之前就被注入了。

autowire= Autowire.BY_NAME 表示依赖的Bean是按名字来自动装配。当然也可以使用autowire= Autowire.BY_TYPE,按类型来装配。

同时我们需要开启SpringConfig支持:

@Configuration
@EnableSpringConfigured
public class AppConfig {
}

最后看下我们怎么调用:

public class ConfigurableApp {

    private static Logger log= LoggerFactory.getLogger(ConfigurableApp.class);

    public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean-config.xml");

        Account accountA=new Account();
        log.info(accountA.getBeanA().toString());

    }
}

输出结果如下:

07:37:27.917 [main] INFO com.flydean.beans.Account - init Account
07:37:27.917 [main] INFO com.flydean.ConfigurableApp - com.flydean.beans.BeanA@54c5a2ff

可以看到虽然Account是new出来的,但是BeanA依然被注入到实例中。

原理

单独使用@Configurable没有任何作用。

Spring-Aspects.jar中的AnnotationBeanConfigurerAspect,才是让@Configurable起作用的根本。本质上,aspect是,“从用@Configurable注解的类型的新对象的初始化返回后,根据注解的属性使用spring配置新创建的对象”。在此上下文中,“初始化”是指新实例化的对象(例如,用new运算符实例化的对象)以及正在进行反序列化的可序列化对象(例如,通过 readResolve())。

重要配置

下面是最最重要的pom配置了,这里我使用了aspectj-maven-plugin 这个插件来对spring-aspects.jar进行编织。 如下所示:



    
        spring5-core-workshop
        com.flydean
        1.0-SNAPSHOT
    
    4.0.0

    aop-advanced
    
        
            org.springframework
            spring-tx
            5.1.3.RELEASE
        

        
            org.springframework
            spring-aspects
            5.1.3.RELEASE
        

    

    
        
        
            
                
                    org.codehaus.mojo
                    aspectj-maven-plugin
                    1.11
                
            
        
        
        
            
                org.codehaus.mojo
                aspectj-maven-plugin

                
                    1.8
                    1.8
                    1.8
                    true
                    true
                    true
                    
                        
                            org.springframework
                            spring-aspects
                        
                    
                


                
                    
                        
                            compile       
                            test-compile  
                        
                    
                
            
        
    

本文的例子可以参考aop-advanced

更多教程请参考 flydean的博客

你可能感兴趣的:(spring,springboot,spring-mvc)