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

简介: 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进行编织。 如下所示:


<?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>
相关文章
|
1月前
|
Java Spring
【编程笔记】在 Spring 项目中使用 RestTemplate 发送网络请求
【编程笔记】在 Spring 项目中使用 RestTemplate 发送网络请求
94 0
|
2月前
|
Java 数据库连接 应用服务中间件
Spring5源码(39)-Aop事物管理简介及编程式事物实现
Spring5源码(39)-Aop事物管理简介及编程式事物实现
24 0
|
3月前
|
Java 程序员 Maven
Spring AOP入门指南:轻松掌握面向切面编程的基础知识
Spring AOP入门指南:轻松掌握面向切面编程的基础知识
|
4月前
|
XML Java 程序员
Spring基础篇:注解编程
Spring基础篇:注解编程
|
6月前
|
Java Spring
【注解】Spring AOP 面向切面编程之@Around的详细用法
【注解】Spring AOP 面向切面编程之@Around的详细用法
285 0
|
6月前
|
XML 设计模式 SQL
spring6-AOP面向切面编程
aop是面向切面编程,本质上是一种代理模式,而代理模式又分为静态代理和动态代理。 静态代理以Aspect J为代表,指的是预编译代理,也即编译时增强,在编译时将代理逻辑织入目标类编译得到的Java字节码文件中,当运行时产生的对象就是增强过后的对象了 动态代理以spring AOP为代表,spring AOP 可以使用JDK动态代理或者CGLIB动态代理实现。
94 1
spring6-AOP面向切面编程
|
5月前
|
缓存 监控 Java
Spring框架之AOP(面向切面编程)
Spring框架之AOP(面向切面编程)
34 0
|
6月前
|
前端开发 Java 数据库连接
Spring Aop:面向切面编程
Spring Aop:面向切面编程
35 0
|
11天前
|
Java 数据库 Spring
切面编程的艺术:Spring动态代理解析与实战
切面编程的艺术:Spring动态代理解析与实战
25 0
切面编程的艺术:Spring动态代理解析与实战
|
3月前
|
XML 存储 Java
JAVAEE框架整合技术之Spring02-AOP面向切面编程技术
JAVAEE框架整合技术之Spring02-AOP面向切面编程技术
54 0
JAVAEE框架整合技术之Spring02-AOP面向切面编程技术