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的配置。
第二行:获取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方法。