spring實現AOP
一、.默認advisor自動代理生成器(實現前置增強)
1.編寫接口類
public interface ISomeService { public void doSome(); public void add(); }
2.實現接口類中的方法
public class SomeService implements ISomeService { public void doSome() { System.out.println("code ok"); } public void add() { System.out.println("=========log==============="); } }
3.編寫增強類
public class MyBeforeAdvice implements MethodBeforeAdvice { public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("執行前置增強"); } }
4.寫配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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="SomeService" class="cn.happy.service.SomeService"></bean> <!--增強 通知--> <bean id="beforeAdvice" class="cn.happy.service.MyBeforeAdvice"></bean><!--前置增強--> <!-- 使用名稱匹配方法切入點顧問NameMatchMethodPointcutAdvisor--> <bean id="beforeAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <!-- <!–顧問 Advisor 包裝通知, 那個方法需要增強–>--> <property name="advice" ref="beforeAdvice"></property> <property name="mappedNames" value="doSome"></property> </bean> <!--默認advisor自動代理生成器 有幾個目標方法都會增強,但是只能對顧問自動代理,不能自動代理通知--> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean> </beans>
5.測試方法
public class test01 { // AspectJ @Test public void testAspect(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ISomeService someService= (ISomeService)context.getBean("SomeService"); someService.add(); someService.doSome(); }
6.測試結果
二、Aspectj實現前置增強
AspectJ:是一個面向切面的框架,它擴展了Java語言。
AspectJ表達式:
語法:execution(表達式) 通過execution函數,可以定義切點的方法切入
execution(<訪問修飾符>?<返回類型><方法名>(<參數>)<異常>)
例如
execution(public * *(..)) 匹配所有類public方法
execution(* cn.study.dao..*(..)) 匹配指定包下所有類方法,不包含子包
execution(* cn.study.dao..*(..)) ..*表示包、子孫包下所有類
execution(* cn.study.service.UserService.*(..)) 匹配指定類所有方法
execution(* cn.study.dao.GenericDAO+.*(..)) 匹配實現特定接口所有類方法
execution(* save*(..)) 匹配所有save開頭的方法
AspectJ增強
@Before 前置通知,相當於BeforeAdvice
@AfterReturning 後置通知,相當於AfterReturningAdvice
@Around 環繞通知,相當於MethodInterceptor
@AfterThrowing拋出通知,相當於ThrowAdvice
@After 最終final通知,不管是否異常,該通知都會執行
1.基本的方法不變,只改一下xml的配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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="SomeService" class="cn.happy.serviceXML.SomeService"></bean> <!-- <!–增強 通知–> 註解 <bean id="beforeAdvice" class="cn.happy.service.MyAspect"></bean> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>--> <!--增強類--> <bean id="aspect" class="cn.happy.serviceXML.MyAspect"></bean> <!--aop--> <aop:config> <!--設置一個切點--> <aop:pointcut id="mycut" expression="execution(* *..serviceXML.*.*(..))"></aop:pointcut> <aop:aspect ref="aspect"> <aop:before method="myBefore" pointcut-ref="mycut"></aop:before> <!--<aop:after-returning method="after" pointcut-ref="mycut"></aop:after-returning>--> <!--<aop:around method="myArround" pointcut-ref="mycut"></aop:around>--> </aop:aspect> </aop:config> </beans>
2.運行後結果
spring實現AOP