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

2年前 (2022) 程序员胖胖胖虎阿
167 0 0

文章目录

  • ​​遇到的问题​​
  • ​​@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;@Autowiredprivate 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@EnableSpringConfiguredpublic 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 Account07: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进行编织。 如下所示:

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>spring5-core-workshop</artifactId><groupId>com.flydean</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>aop-advanced</artifactId><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.1.3.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.1.3.RELEASE</version></dependency></dependencies><build><!-- To define the plugin version in your parent POM --><pluginManagement><plugins><plugin><groupId>org.codehaus.mojo</groupId><artifactId>aspectj-maven-plugin</artifactId><version>1.11</version></plugin></plugins></pluginManagement><!-- To use the plugin goals in your POM or parent POM --><plugins><plugin><groupId>org.codehaus.mojo</groupId><artifactId>aspectj-maven-plugin</artifactId><configuration><complianceLevel>1.8</complianceLevel><source>1.8</source><target>1.8</target><outxml>true</outxml><verbose>true</verbose><showWeaveInfo>true</showWeaveInfo><aspectLibraries><aspectLibrary><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId></aspectLibrary></aspectLibraries></configuration><executions><execution><goals><goal>compile</goal>       <!-- use this goal to weave all your main classes --><goal>test-compile</goal>  <!-- use this goal to weave all your test classes --></goals></execution></executions></plugin></plugins></build></project>

版权声明:程序员胖胖胖虎阿 发表于 2022年10月3日 上午1:40。
转载请注明:Spring5参考指南:AspectJ高级编程之Configurable | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...