使用ProxyFactoryBean之前先來了解一下它的屬性
- target屬性:指明要代理的目標類 ,這個目標類實現了上面proxyInterfaces屬性指定的接口。
- proxyInterfaces屬性:指明要代理的接口。
- interceptorNames屬性:指明要在代理的目標類中添加的功能,即advice 。
- proxyTargetClass屬性:,如果這個屬性被設定為“true”,說明 ProxyFactoryBean要代理的不是接口類,而是要使用CGLIB方式來進行代理。默認值為false,如果是要代理的是接口就采用JDK進行動態代理,如果要代理的不是接口類就采用cglib代理
了解完ProxyFactoryBean的重要的幾個屬性之后,我們就用ProxyFactoryBean的方式來進行一個環繞增強
第一步:創建一個業務類
package com.yjc.autoproxys; public class DoSomeServiceImpl { public void doSome() { System.out.println("doSome==============================="); } public void doSome2() { System.out.println("doSome2=========================================="); } }
第二步:創建增強類,實現環繞增強要實現的MethodInterceptor 接口,重寫invoke
package com.yjc.aroundproxy;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.ThrowsAdvice;
public class AroundProxyAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("前置===============");
//用於啟動目標方法執行的
Object proceed = invocation.proceed();
System.out.println("后置===============");
return proceed;
}
}
第三步:在Spring的核心配置文件中實現增強
<?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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--將增強類和目標業務都放入到Spring容器中--> <bean id="advice" class="com.yjc.aroundproxy.AroundProxyAdvice"></bean> <bean id="dosome" class="com.yjc.aroundproxy.DoSome"></bean> <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyTargetClass" value="true"/> <property name="interceptorNames" value="advice"/> <!--如果用多種增強方式,value的值使用逗號(,)分割--> <property name="target" ref="dosome"/> </bean> </beans>
第四步:測試類
package com.yjc.aroundproxy; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AroundProxyTest { public static void main(String[] args) { ApplicationContext applicationContext=new ClassPathXmlApplicationContext("com/yjc/aroundproxy/application_aroundproxy.xml"); DoSome proxyFactory = applicationContext.getBean("proxyFactoryBean", DoSome.class); proxyFactory.doSome(); proxyFactory.doSome2(); } }
測試成功
其他的增強方式除了(最終增強)之外,都可以使用ProxyFactoryBean來進行實現
使用aop:config的方式進行異常和最終增強
第一步:在業務類里添加一個除零異常
package com.yjc.error; public class DoSomeServiceImpl { public void doSome()throws Exception { int i=1/0; System.out.println("doSome==============================="); } public void doSome2() { System.out.println("doSome2=========================================="); } }
第二步:定義增強類,添加異常增強方法,和最終增強方法
package com.yjc.error; import org.aspectj.lang.JoinPoint; import org.springframework.aop.AfterReturningAdvice; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; public class ErrorAdvice { //異常增強 public void afterThrowing(JoinPoint joinPoint,RuntimeException e){ System.out.println(joinPoint.getSignature().getName()+"發生異常"+e); } //最終增強 public void afterAdvice(){ System.out.println("最終增強=============="); } }
第三步:在Spring的核心配置文件中實現增強
<?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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="doSomeService" class="com.yjc.error.DoSomeServiceImpl"></bean> <bean id="advice" class="com.yjc.error.ErrorAdvice"></bean> <aop:config> <aop:pointcut id="pointcut" expression="execution(* com.yjc.error.*.*(..))" /> <aop:aspect ref="advice"> <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/> <!--throwing中的e是你異常增強方法中的參數名--> <aop:after method="afterAdvice" pointcut-ref="pointcut"/> </aop:aspect> </aop:config> </beans>
第四步:測試
package com.yjc.error; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class ErrorTest { public static void main(String[] args) { ApplicationContext applicationContext=new ClassPathXmlApplicationContext("com/yjc/error/application_error.xml"); DoSomeServiceImpl proxyFactory = applicationContext.getBean("doSomeService", DoSomeServiceImpl.class); try { proxyFactory.doSome(); } catch (Exception e) { e.printStackTrace(); } proxyFactory.doSome2(); } }
測試
由上圖可知我們的增強已經成功了,雖然在dosom方法里發生了異常,但是dosome的最終增強還是執行了,異常處理的目標就是,程序中發生了異常,把他吞掉不會影響后續模塊的執行, 我們在測試方法把有可能出現異常的dosome方法放到了try-catch中,發生異常之后並不影響dosome2方法的執行