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>
本文的例子可以参考aop-advanced
更多教程请参考 flydean的博客
Spring5参考指南:AspectJ高级编程之Configurable的更多相关文章
- Spring5参考指南:AspectJ注解
文章目录 什么是AspectJ注解 启用AOP 定义Aspect 定义Pointcut 切入点指示符(PCD) 切入点组合 Advice 访问JoinPoint Advice参数 Advice参数和泛 ...
- Spring5参考指南:IOC容器
文章目录 为什么使用Spring5 什么是IOC容器 配置元数据 实例化容器 XML嵌套 groovy bean定义DSL 使用容器 最近在翻译Spring Framework Documentati ...
- Python Flask高级编程之RESTFul API前后端分离精讲 (网盘免费分享)
Python Flask高级编程之RESTFul API前后端分离精讲 (免费分享) 点击链接或搜索QQ号直接加群获取其它资料: 链接:https://pan.baidu.com/s/12eKrJK ...
- Python Flask高级编程之从0到1开发《鱼书》精品项目 ☝☝☝
Python Flask高级编程之从0到1开发<鱼书>精品项目 ☝☝☝ 一 .安装环境我们使用 flask web框架,并用 sqlalchemy来做数据库映射,并使用 migrate做数 ...
- Python Flask高级编程之从0到1开发《鱼书》精品项目 ✍✍✍
Python Flask高级编程之从0到1开发<鱼书>精品项目 一 .安装环境我们使用 flask web框架,并用 sqlalchemy来做数据库映射,并使用 migrate做数据迁移 ...
- Python Flask高级编程之从0到1开发《鱼书》精品项目
Python Flask高级编程之从0到1开发<鱼书>精品项目 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感 ...
- Spring5参考指南:依赖注入
文章目录 依赖注入 依赖注入的配置详解 depends-on lazy-init 自动装载 方法注入 依赖注入 依赖注入就是在Spring创建Bean的时候,去实例化该Bean构造函数所需的参数,或者 ...
- Spring5参考指南:AOP代理
文章目录 AOP代理 AOP Proxies原理 AOP代理 通常来说Spring AOP有两种代理方式,一种默认的JDK代理,只能代理接口,一种是CGLIB代理,可以代理具体的类对象. Spring ...
- Spring5参考指南:基于Schema的AOP
文章目录 基于Schema的AOP 定义Aspect 定义Pointcut 定义Advice advice参数 Advisors 基于Schema的AOP 上篇文章我们讲到了使用注解的形式来使用Spr ...
随机推荐
- 001_创建一个sidebar切换页面
Table Of Content 准备 基本思路 实现 我们期望实现这样的效果: ![](https://img2018.cnblogs.com/blog/1735896/202001/1735896 ...
- vue 跳转 同一路由不刷新问题解决
vue跳转同一路径时,路由参数改变,但页面无法更新 问题原因 vue路由切换实际是组件间的切换,引用相同组件的时候,页面就无法更新 解决方案 方案1.watch监听路由参数变化,并重新渲染(谨慎选择) ...
- 1004 Counting Leaves (30 分)
A family hierarchy is usually presented by a pedigree tree. Your job is to count those family member ...
- Linux基础:Day01
Linux操作系统的知识体系: 1.初级 2.中级 3.高级 4.*额外知识* 1.初级 1.1.OS操作系统的原理 1.2.开始了解常用的命令(系统管理的基础命令) 开机关机 时 ...
- Hadoop(八):YARN框架简介
YARN组件图 Container是YARN框架中对应资源的抽象,封装了运行节点上的资源(内存+CPU) NodeManager负责Container状态的维护,通过心跳,把资源信息(剩余CPU.内存 ...
- ConcurrentHashMap中节点数目并发统计的实现原理
前言: 前段时间又看了一遍ConcurrentHashMap的源码,对该并发容器的底层实现原理有了更进一步的了解,本想写一篇关于ConcurrentHashMap的put方法所涉及的初始化以及扩容操作 ...
- json.dumps() 和 json.loads()
转载: https://blog.csdn.net/qinglingls/article/details/96476368
- 30.4 Map HashMap
本文将会讲解到: Map和Collection的对比 Map接口的使用,实现类HashMap的使用 /* * 需求:实现学号和姓名这样有对应关系的数据存储 * 为了体现这种有对应关系的数据,我们使用以 ...
- Array(数组)对象-->shift() 方法
1.定义和用法 shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值. 语法: array.shift() 注意: 此方法改变数组的长度! 举例: var arr = [1,2, ...
- tf.train.AdamOptimizer 优化器
adaptive moment estimation(自适应矩估计) tf.train.AdamOptimizer( learning_rate=0.001, beta1=0.9, beta2=0.9 ...