需要的Jar包(String3.2)
com.springsource.net.sf.cglib-2.2.0.jar // 作用于cglib方式的动态代理
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring-aop-3.2.0.RELEASE.jar 五种增强模式
1、前置增强【before】,在业务代码之前执行增强的服务代码
示例代码如下:
AopUtil.java
1 // 服务类定义 2 public class AopUtil { 3 // 增强函数 4 public void showLog(){ 5 System.out.println("调用服务类功能成功!"); 6 } 7 }
Bean.java
1 // 业务类实现 2 public class Bean { 3 // 具体业务功能实现 4 public void callBean(){ 5 System.out.println("调用Bean业务类功能成功!"); 6 } 7 } 配置文件 spring.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 9 10 http://www.springframework.org/schema/aop 11 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> 12 13 <bean id="beanID" class="aop.xml.Bean" ></bean> 14 <bean id="utilID" class="aop.xml.AopUtil"></bean> 15 16 <aop:config proxy-target-class="true"> 17 <aop:pointcut expression="execution(public * *.*(..))" id="pcID"/> 18 19 <aop:aspect ref="utilID" > 20 <aop:before method="showLog" pointcut-ref="pcID" /> 21 </aop:aspect> 22 </aop:config> 23 24 </beans> TestSpring.java
1 // 程序入口 2 public class TestSpring { 3 public static void main(String[] args) { 4 ApplicationContext ac = new ClassPathXmlApplicationContext( 5 new String[] { "aop/xml/spring.xml" }); 6 Bean bean = (Bean) ac.getBean("beanID"); 7 bean.callBean(); 8 } 9 } 2、后置增强【after】,在业务代码之后执行执行增强的服务代码,与前置增强区别仅在于XML文件中对aop的配置
1 <aop:config proxy-target-class="true"> 2 <aop:pointcut expression="execution(public * *.*(..))" id="pcID"/> 3 4 <aop:aspect ref="utilID" > 5 <aop:after method="showLog" pointcut-ref="pcID" /> 6 </aop:aspect> 7 </aop:config> 3、正常返回后增强【after-returning】,业务代码正确执行后才会执行服务代码,也就是说若业务代码如果有异常,服务代码就不会执行
1 <aop:config proxy-target-class="true"> 2 <aop:pointcut expression="execution(public * *.*(..))" id="pcID"/> 3 4 <aop:aspect ref="utilID" > 5 <aop:after-returning method="showLog" pointcut-ref="pcID" /> 6 </aop:aspect> 7 </aop:config> 4、异常后增强【after-throwing】,与after-returning的执行过程相反
1 <aop:config proxy-target-class="true"> 2 <aop:pointcut expression="execution(public * *.*(..))" id="pcID"/> 3 4 <aop:aspect ref="utilID" > 5 <aop:after-throwing method="showLog" pointcut-ref="pcID" /> 6 </aop:aspect> 7 </aop:config> 5、方法环绕增强【around】
1 <aop:config proxy-target-class="true"> 2 <aop:pointcut expression="execution(public * *.callBean(..))" id="pcID"/> 3 4 <aop:aspect ref="utilID" > 5 <aop:around method="writeLog" pointcut-ref="pcID" /> 6 </aop:aspect> 7 </aop:config>
1 // 服务类定义 2 public class AopUtil { 3 4 public void writeLog(ProceedingJoinPoint point) throws Throwable{ 5 System.out.println("调用服务类功能【writeLog】成功!"); 6 point.proceed(); 7 } 8 } 方法环绕增强与前面四种增强的主要区别在于,业务代码调用的控制在服务类的增强函数中 point.proceed()
XML方式配置stringAop总结:
确定动态代理方式JDK还是CGILIB有proxy-target-class属性字段的值确定,false表示采用JDK自带的动态代理,true表示采用 CGLIB动态代理;确定切入点即业务类中实现的业务方法,由属性值aop:pointcut expression确定,id=”pcID”建立业务方法的ID值execution属性值格式:
execution(修饰符 返回值 包名.类名.方法名(参数) 异常),其中修饰符、包名、类名、异常可以省略也支持通配符*,返回类型、方法名、参数不能省略但支持通配符*;
业务方法与服务方法建立关系由aop:aspect配置确定,ref=”utilID”指定服务类对象,
<aop:增强方式 method=增强方法 pointcut-ref=业务方法ID值 />
注解方式实现stringAop示范例代码:
spring.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xmlns:context="http://www.springframework.org/schema/context" 7 8 xsi:schemaLocation=" 9 http://www.springframework.org/schema/beans 10 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 11 12 http://www.springframework.org/schema/aop 13 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 14 15 http://www.springframework.org/schema/context 16 http://www.springframework.org/schema/context/spring-context-3.0.xsd" > 17 18 <!-- 打开注解开关, 开关打开后才能解析@符号表示的注解 --> 19 <context:annotation-config /> 20 <!-- 扫描指定包下的注解,也就是指定需解析注解的路径 --> 21 <context:component-scan base-package="annotation"></context:component-scan> 22 <!-- 告诉springAop,产生业务类的动态代理对象,并切入到对应服务类方法中 --> 23 <aop:aspectj-autoproxy/> 24 </beans> Bean.java
1 // 业务类实现 2 //@Component表示业务Bean实例化 3 @Component(value="beanID") 4 public class Bean { 5 // 具体业务功能实现,通过@Pointcut注解注册切入点 6 @Pointcut (value="execution(public * *.callBean(..))") 7 public void callBean(){ 8 System.out.println("调用Bean业务类功能成功!"); 9 } 10 } AopUtil.java
1 // 服务类定义 2 //@Aspect表示AopUtil为切面,@Component(value="aopUtilID")对AopUtil类进行实例化 3 @Aspect 4 @Component(value="aopUtilID") 5 public class AopUtil { 6 // @Before确定为增强模式为前置增强,value的值表示增强的业务函数 7 @Before (value="annotation.Bean.callBean()") 8 public void writeLog(){ 9 System.out.println("调用服务类功能【writeLog】成功!"); 10 } 11 } TestSpring.java // 程序入口
1 public class TestSpring { 2 public static void main(String[] args) { 3 ApplicationContext ac = new ClassPathXmlApplicationContext( 4 new String[] { "annotation/spring.xml" }); 5 Bean bean = (Bean) ac.getBean("beanID"); 6 bean.callBean(); 7 } 8 } 注解说明:
@Component(value=自定义ID名称)作用于需实例化的类,并将实例化后的类对象加入Bean工厂;
@Aspect 指定作用于springAop中的切面类;
@Before (value="业务方法名")指定springAop中增强模式及需要增强的业务方法,业务方法名需带包名;
@Pointcut (value="execution表达式)") 指定springAop切入点业务方法;
@Resource(name="自定义ID名称")在Bean工厂中查找对应的ID名称对象,并注入到修饰的方法中,例子如下:
1 private Unit unit; 2 @Resource(name="unitID") 3 public void setUnit(Unit unit) { 4 this.unit = unit; 5 } 0 0