一,测试demo
配置切面通知类:
@Aspect
public class LogAspects {
@Pointcut("execution(* com.myProject.Myspring.User.*(..))")
public void pointCut(){}
@Before("pointCut()")
public void logStart(){
System.out.println("before() ------------------");
}
@After("pointCut()")
public void logEnd(){
System.out.println("end() ---------------------");
}
@AfterReturning("pointCut()")
public void logReturn(){
System.out.println("return() -------------------");
}
}
第一个注意的是切面点匹配表达式,如果匹配成扫描一个包下面的bean,由于我包下面不是所有都是准备自动注入的bean,所以产生了循环依赖的问题,一定要注意这个通知bean的范围!
第二个注意,这里使用的@Aspect标签,需要导入两个包:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
然后使用注解启动的方式,在注解配置类中,标注两个bean,并且开启aop
@Configuration
@EnableAspectJAutoProxy
public class MainConfig {
@Bean
public User user(){
return new User();
}
@Bean
public LogAspects logAspects(){return new LogAspects();}
}
被监视的bean:
public class User {
private String name;
private int price=30;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getPrice(){
System.out.println("获得价格:"+price);
return price;
}
}
测试类:
public class App
{
public static void main( String[] args )
{
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfig.class);
User user=(User)applicationContext.getBean("user");
user.getPrice();
}
}
测试结果:
二,源码分析
Spring Aop 是由接入BeanPostProcessor后置处理器开始的,Bean后置处理器是一个监听器,可以监听容器触发的Bean生命周期事件,向容器注册后置处理器以后,容器中管理的Bean就具备了接收IOC容器回调事件的能力。
BeanPostProcessor的调用发生在AbstractAutowireCapableBeanFactory类的doCreateBean()方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean. 创建bean实例对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) { //单例,用过已经存在与缓存中,获取
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) { //临时创建
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
....
// Initialize the bean instance.
Object exposedObject = bean;
try { //对Bean属性进行依赖注入
populateBean(beanName, mbd, instanceWrapper);
//对Bean实例对象进行初始化,使用后置处理器
exposedObject = initializeBean(beanName, exposedObject, mbd); //← ← ←
}
...
return exposedObject; //返回结果
}
从上面的代码中可见,入口是在initializeBean()方法中:也就是创建Bean-Bean的依赖注入--Bean的初始化
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
...
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//【1】
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//【2】
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}....
//【3】
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
1.applyBeanPostProcessorBeforeInitialization()
调用后置处理器(BeanPostProcessor)的,回调方法,做一些bean初始化前的处理,先看一下后置处理器接口:
public interface BeanPostProcessor {
default Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
default Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
一共两个方法,一个before(),一个是after()。
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//遍历容器为所创建的Bean添加所有BeanPostProcessor后置处理器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName); //调用before()
if (current == null) {
return result;
}
result = current;
}
return result;
}
首先是获得BeanPostProcessor,重点是调用AbstractAutoProxyCreator类的方法,不做任何处理:
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
遍历这个处理器链,如何返回的null,那么就返回最后结果,如果不为空,则继续。注意传入的参数,这里是一种链式的感觉。
2.invokeInitMethods()
调用bean实例初始化方法,初始化方法是由spring bean定义配置文件中通过init-Method属性指定的
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd){
boolean isInitializingBean = (bean instanceof InitializingBean);
....
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd); //【入】
}
}
}
基本逻辑就是,找到该方法method,然后使用反射执行
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) {
String initMethodName = mbd.getInitMethodName();
final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
....
if (initMethod == null) {
return;
}
...
try {
ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean); //反射执行
}
3.applyBeanPostProcessorsAfterInitialization()
调用BeanPostProcessor后置处理器的,实例初始化之后的处理方法,处理逻辑和before()一样
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
上面的代码就是调用具体的BeanPostProceesor的实现方法,这里的postProcessBefore..()方法是接口,同样中带你是后置处理器:AbstractAutoProxyCreator类中:
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName); //存的应该是字符串
if (this.earlyProxyReferences.remove(cacheKey) != bean) { //如果已经代理了,则删除并返回
return wrapIfNecessary(bean, beanName, cacheKey); //【入】
}
}
return bean;
}