aop介紹
AOP(Aspect Oriented Programming),即面向切面編程,能夠說是OOP(Object Oriented Programming,面向對象編程)的補充和完善。
面向切面是面向對象中的一種方式而已。在代碼執行過程當中,動態嵌入其餘代碼,叫作面向切面編程。常見的使用場景:
i :日誌
ii: 事務
iii:數據庫操做
spring
aop的實現方式(schema)
前置通知(MethodBeforeAdvice)數據庫
@Component public class MyBeforeAdvice implements MethodBeforeAdvice{ @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("前置通知執行:"+method.getName()); } }
後置通知(AfterReturningAdvice)express
@Component public class AfterAdvice implements AfterReturningAdvice{ @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("後置通知 :"+returnValue); }
環繞通知(MethodInterceptor)編程
@Component public class AroundInterceptor implements MethodInterceptor{ @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("環繞通知執行1"); String msg = (String)invocation.proceed(); System.out.println("環繞通知執行2"); return msg==null?null:msg.toUpperCase(); } }
異常處理通知(ThrowsAdvice)app
@Component public class MyThrowsAdvice implements ThrowsAdvice { public void afterThrowing(Exception ex){ System.out.println("異常參數了:"+ex.getMessage()); } }
測試類框架
public class Test { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); IWindow window = ac.getBean("mytarget",IWindow.class); window.say(); System.out.println("----------"); System.out.println(window.doSome()); } }
applicationContext.xml配置文件 ide
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <!-- 開啓掃描 --> <context:component-scan base-package="com.sxt.*"></context:component-scan> <!-- 1.註冊目標對象 --> <!-- <bean class="com.sxt.pojo.Window" id="window"/> 2.註冊前置通知對象--> <bean class="com.sxt.advice.MyBeforeAdvice" id="methodBeforeAdvice"/> <bean class="com.sxt.advice.AfterAdvice" id="afterAdvice"></bean> <bean class="com.sxt.advice.AroundInterceptor" id="around"></bean> <bean class="com.sxt.advice.MyThrowsAdvice" id="myThrowsAdvice"></bean> <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="mytarget"> <property name="target" ref="window" /> <property name="interfaces" value="com.sxt.pojo.IWindow" /> <property name="interceptorNames"> <array> <!-- 關聯前置通知 --> <value>methodBeforeAdvice</value> <value>afterAdvice</value> <value>aroundInterceptor</value> <value>myThrowsAdvice</value> </array> </property> </bean> </beans>
基於aspectJ方式實現
對於AOP這種編程思想,不少框架都進行了實現。Spring就是其中之一,能夠完成面向切面編程。然而,AspectJ也實現了AOP的功能,且其實現方式更爲簡捷,使用更爲方便,並且還支持註解式開發。因此,Spring又將AspectJ的對於AOP的實現也引入到了本身的框架中。在Spring中使用AOP開發時,通常使用AspectJ的實現方式
測試
xml配置的方式spa
實體類3d
public class Window implements IWindow{ @Override public void say(){ System.out.println("div dir"); } @Override public String doSome(){ System.out.println("你好"); return "hello"; } }
切面類
public class Advice{ public void before(){ System.out.println("前置通知"); } public void afterReturning(){ System.out.println("後置通知"); } public Object around(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("環繞通知1"); Object msg = pjp.proceed(); if (msg != null) { msg = msg.toString().toUpperCase(); System.out.println("環繞通知2"); return msg; } return null; } public void throwing(Exception ex){ System.out.println("參數異常了:"+ex.getMessage()); } public void after(){ System.out.println("最終通知"); } }
測試類
public class Test { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); IWindow window = ac.getBean(IWindow.class); window.say(); System.out.println("----------"); System.out.println(window.doSome()); } }
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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" 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/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!-- 註冊目標對象 --> <bean class="com.sxt.pojo.Window" id="window"></bean> <!-- 註冊切面對象 --> <bean class="com.sxt.advice.Advice" id="myAdvice"></bean> <!-- 3.配置AOP --> <aop:config> <!-- 配置切面對象 --> <aop:aspect ref="myAdvice"> <!-- 配置切面點 --> <aop:pointcut expression="execution(* com.sxt.pojo.*.*(..))" id="pointcut"/> <aop:after-returning method="afterReturning" pointcut-ref="pointcut"/> <aop:before method="before" pointcut-ref="pointcut"/> <aop:around method="around" pointcut-ref="pointcut"/> <aop:after-throwing method="throwing" pointcut-ref="pointcut" throwing="ex"/> <aop:after method="after" pointcut-ref="pointcut"/> </aop:aspect> </aop:config> </beans>
註解的方式
切面類
@Component @Aspect public class Advice{ @Before(value="execution(* com.sxt.*.*.*(..))") public void before(){ System.out.println("前置通知"); } @AfterReturning(value="execution(* com.sxt.*.*.*(..))") public void afterReturning(){ System.out.println("後置通知"); } @Around(value="execution(* com.sxt.pojo.*.*(..))") public Object around(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("環繞通知1"); Object msg = pjp.proceed(); if (msg != null) { msg = msg.toString().toUpperCase(); System.out.println("環繞通知2"); return msg; } return null; } @AfterThrowing(value="execution(* com.sxt.pojo.*.*(..))",throwing="ex") public void throwing(Exception ex){ System.out.println("參數異常了:"+ex.getMessage()); } @After(value="execution(* com.sxt.pojo.*.*(..))") public void after(){ System.out.println("最終通知"); } }
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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" 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/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!-- 開啓掃描 --> <context:component-scan base-package="com.sxt.*"></context:component-scan> <!-- 開啓aspectJ註解 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
控制檯輸入