详述SpringAOP实现及执行过程

application.xml中代码:

        
	

Test中代码:

public class Test {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		ICalculatorService calculatorService = applicationContext.getBean(ICalculatorService.class );
		int result = calculatorService.mul(1, 1);
		System.out.println("-->"+result);
		applicationContext.close();
	}
}

 CalculatorAspect中代码:

@Aspect
@Component //将CalculatorAspect类创建对象并保存到容器中
public class CalculatorAspect {

	@Before("execution(int mul(..))")
	public void before(JoinPoint jp) {
		Object object = jp.getTarget(); //产生目标类的对象
		Object [] args = jp.getArgs();
		String name=jp.getSignature().getName();
		System.out.println(this.getClass().getName()+":The "+name +" method begins.");
		System.out.println(this.getClass().getName()+":Parameters of the mul method: ["+args[0]+","+args[1]+"]");
	}
	
	@AfterReturning(value="execution(int mul(..))",returning="a")
	public void afterReturning(JoinPoint jp,Object a) {
		Object object = jp.getTarget();
		String name= jp.getSignature().getName();
		System.out.println(this.getClass().getName()+":Result of the "+name +" method:"+a);

	}
}

 分析代码

1.application.xml:

    ①扫描com.jd包中的类,及其子包中的类

 

      ②寻找过程:  autoproxy:Spring寻找@Aspect类(CalculatorAspect)——>寻找该类中方法(before,after)——>获取方法注解 (@Before,@After)——> 获取表达式(execution(int mul(int , int )))——>检查Spring能扫描到的所有类,找到与表达式匹配的方法以及对应的类——>为该类创建动态对象

        proxy-target-class="false"时,使用的是默认的动态代理方式jdk动态代理,当proxy-target-class="true"时,使用的是GCLib动态代理。想知道使用的是jdk动态代理对象还是CGLib动态代理对象,可以在Test.java的mian方法中用System.out.println(calculatorService.getClass().getName()); 来输出

2. Test:

      ①创建Spring容器,在非懒加载的情况下,为在com.jd包及其子包内加有注解@component,@repository,@Service, @controller的类创建对象 

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");

       ②创建动态代理对象

 

ICalculatorService calculatorService = applicationContext.getBean(ICalculatorService.class);

      ③调用mul()方法,和jbc中一样

int result = calculatorService.mul(1, 1);

3.CalculatorAspect

  ① 注解:@Aspect是做的标记(切面),@Component将CalculatorAspect类创建对象并保存到容器中

  ②产生目标类的对象

Object object = jp.getTarget();

   ③获得传入方法的参数值,并存放到args数组中

joinPoint.getArgs()

   ④获取到调用的方法的名字

String name=jp.getSignature().getName();

 代码执行过程

 Test.java中main方法:

第一行:1:执行时会查看application.xml的配置。在非懒加载的情况下,会扫描com.jd包及其子包内,标有注解@component,@repository,@Service,@controller的类创建对象。2:执行.时,Spring会寻找标有@Aspect的类,也就是上面代码段中的CalculatorAspect类。3:寻找该类中方法(before,after)。4:获取方法注解 (@Before,@After)。5: 获取表达式。比如:@Before("execution(int mul (int ,int))")中的("execution(int mul (int ,int))")。6:检查Spring能扫描到的所有类,也就是扫描到的类,找到与表达式匹配的方法所对应的类。7:为该类创建动态对象

第二行:获取application.xml文件中创建的动态对象。

      注意:在使用jdk动态代理时,getBean(ICalculatorService.class)中的参数必须是ICalculatorService.class,因为jdk动态代理类($Proxy.class)实现了接口,但是和CalculatorService类是兄弟关系的;

                在使用CGLib动态代理时,可以是ICalculatorService.class也可以是CalculatorService.class,因为CGLib动态代理类继承了CalculatorService,是父子关系。
第三行:调用动态对象的mul方法,和jdk动态代理中add方法的执行过程一致

        注意:先执行before方法,然后执行CalculatorService.java中的mul方法,最后再执行CalculatorAspect.java中的after方法。

 

你可能感兴趣的:(详述SpringAOP实现及执行过程)