1. 創建通知:定義一個接口
public interface Sleepable{ void sleep(); } 然後寫一個Human類,他實現了這個接口 public Human implements Sleepable{ public void sleep(){ System.out.println("睡覺中...!"); } }
2.編寫一個SleepHelper類,它裡面包含了睡覺的輔助工作,用AOP術語來說它就應該是通知
public class SleepHelper implements MethodBeforeAdvice,AfterReturningAdvice { public void before(Method method, Object[] arguments, Object target) throws Throwable { System.out.println("睡覺前"); } public void afterReturning(Object rturnValue, Method method, Object[] arguments, Object target) throws Throwable { System.out.println("睡覺後"); } }
然後在spring配置文件中進行配置:
<!-- 被代理目標對象 -->
<bean id="Human" class="cn.happy.dao.Human"></bean> <bean id="SleepHelper" class="cn.happy.aop.SleepHelper"></bean> //定義切點的常用的兩種方式:1)使用正則表達式 2)使用AspectJ表達式, //這裡用正則表達式 <!-- 顧問 --> <bean id="BeforAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="BeforAdvice"></property> <property name="pattern" value=".*l.*g.*"></property> </bean> <!-- 代理對象 --> // ProxyFactoryBean是一個代理,我們可以把它轉換為 //proxyInterfaces中指定的實現該interface的代理對象 <bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="Human"></property> <property name="interceptorNames" value="BeforAdvisor"></property> </bean>
代理類
public class StuTest { public static void main(String[] args) { //通過ClassPathXmlApplicationContext實例化Spring的上下文 ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); //通過ApplicationContext的getBean()方法,根據id來獲取Bean的實例 Sleepable s=(Sleepable)context.getBean("Human"); s.sleep(); } }
用@Aspect的注解來標識切面
@Aspect//該類為切面 public class MyAspect { @Before(value="execution(public * *(..))") public void mybefore(){ System.out.println("前置增強"); } //後置增強 @AfterReturning(value="execution(public * *(..))") public void myafterReturning(){ System.out.println("後置增強"); } //異常增強 @AfterThrowing(value="execution(public * *(..))") public void myafterThrowing(){ System.out.println("異常增強"); } //環繞增強 @Around(value="execution(public * *(..))") public void myAround(ProceedingJoinPoint jp){ System.out.println("環繞前增強"); try { jp.proceed(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("環繞後增強"); } //最終增強 @After(value="execution(public * *(..))") public void myafterLogger(){ System.out.println("最終增強"); } }
Spring配置文件:
<!-- 目標對象 --> <bean id="Human" class="cn.happy.dao.IserviceImpl"></bean> <!-- 切面: --> <bean id="myAspect" class="cn.happy.aop.MyAspect"></bean> <aop:aspectj-autoproxy/>
測試類
public class StuTest { public static void main(String[] args) { ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); Sleepable s=(Sleepable)context.getBean("Service"); s.sleep(); } }
<aop:advisor> 定義一個AOP通知者
<aop:after> 後通知
<aop:after-returning> 返回後通知
<aop:after-throwing> 拋出後通知
<aop:around> 周圍通知
<aop:aspect>定義一個切面
<aop:before>前通知
<aop:config>頂級配置元素,類似於<beans>這種東西
<aop:pointcut>定義一個切點
public class MyAspect { public void mybefore(){ System.out.println("前置增強"); } public String myafterReturning(String Returning){ System.out.println("前置增強"); return Returning; } }
public class IserviceImpl implements Iservice{ public void log() { System.out.println("開啟事務"); } public String dofirst() { System.out.println("記錄日志"); return ""; } }
Spring的配置文件:
<!-- 目標對象 --> <bean id="Service" class="cn.happy.dao.IserviceImpl"></bean> <!-- 切面: --> <bean id="myAspect" class="cn.happy.aop.MyAspect"></bean> <!-- 配置切面 --> <aop:config> <!-- 配置切入點 --> <aop:pointcut id="pointcut" expression="execution(public * *..Iservice.log(..))"/> <!-- 將類方法定義為最終增強並引用pointcut切入點--> <aop:aspect ref="myAspect"> <aop:after method="myafterReturning" pointcut-ref="pointcut"/> </aop:aspect> </aop:config>
測試類
public class SpringTest { public static void main(String[] args) { ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); Iservice bean = (Iservice)context.getBean("Service"); bean.log(); String count=bean.dofirst(); System.out.println(count); } }