spring源码---Aop:调用过程

一,测试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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值