AOP可用于增加事务、日志、监控等功能,而不需要去逐个修改业务代码。现在需要给IoC例子中的Hello的方法增加日志记录的功能:修改配置文件beans.xml,增加记录日志的类LogHello,java,再加两个jar包aspectjweaver.jar、cglib-nodep-2.1_3.jar。
beans.xml修改如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<bean name="hello" class="Hello">
<constructor-arg>
<value>World</value>
</constructor-arg>
<!--
<property name="name">
<value>Spring</value>
</property>
-->
</bean>
<bean name="log" class="LogHello"/>
<aop:config>
<aop:aspect id="myAop" ref="log">
<aop:pointcut id="servicesPointcut" expression="execution(* *.*(..))"/>
<aop:after method="addLog" pointcut-ref="servicesPointcut" />
</aop:aspect>
</aop:config>
</beans>
加一个LogHello.java:public class LogHello {
public void addLog(){
System.out.println("logHello");
}
}
运行TestSpring.java ,输出结果:
Hello World
logHello
配置文件中<aop:config>标签的意思是:将LogHello的实例log作为切面,expression定义了切入点(第一个*——返回值,第二个*——类,第三个*——方法,括号中的参数)为所有类的所有方法。<aop:after>表示所有符合切入点的方法执行完后,会执行切面的addLog方法。
AOP怎么实现?
1.使用动态代理创建hello的代理类。切入点,切面等对象的实例化是使用IoC来完成的。ConfigBeanDefinitionParser中解析<aop>的标签保存到相应的BeanDefinition中。AbstractAutoProxyCreator中在创建代理对象的时候将切面类等织入。
2.执行方法的时候,会执行代理类的invoke,进而调用ReflectiveMethodInvocation.proceed(),遍历所有切面,判断切入点,逐个执行符合条件切面。