Spring學習-AOP
阿新 • • 發佈:2020-08-06
Spring學習-AOP
AOP
注意:需要在pom.xml中匯入包:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
方式一:基於XML檔案實現AOP(不定義切面)
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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--託管bean--> <bean id="target" class="com.example.demo.aop.TargetDemo"/> <bean id="log" class="com.example.demo.aop.Log"/> <bean id="security" class="com.example.demo.aop.Security"/> <!--定義AOP--> <aop:config> <!--AOP配置--> <!--定義切點,表示被切入的物件和方法--> <aop:pointcut id="pointcut" expression="execution(* com.example.demo.aop.TargetDemo.*(..))"/> <!--在切點上定義一個前置通知--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <!--在切點上定義一個後置通知--> <aop:advisor advice-ref="security" pointcut-ref="pointcut"/> </aop:config> </beans>
Java類:
// 切點類:表示該類方法被呼叫時,會先、後呼叫前置、後置通知 public class TargetDemo implements ITarget{ public void doMyThings() { System.out.println("target object is running"); } } // 通知類:方法執行前通知 public class Log implements MethodBeforeAdvice { @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("日誌應該先被執行"); } } // 通知類:方法返回後進行通知 public class Security implements AfterReturningAdvice { @Override public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { System.out.println("安全應該在目標物件後執行"); } } // 測試類 public class MyTest { @Test public void test() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("aop.xml"); ITarget bean = context.getBean("target", ITarget.class); bean.doMyThings(); // 方法被呼叫時,會先後呼叫對應的通知方法 } }
方式二(自定義切面)
切面:一個類,設定一些前置通知,後置通知等方法,切入到切點中。
XML檔案:
<!--切面類,其中的方法可以切入到切點中--> <bean id="aop" class="com.example.demo.test.AOP"/> <aop:config> <aop:aspect ref="aop"><!--定義一個切面,為一個類,其中的方法可以切入到切點中--> <!--定義切點,在執行方法時,會被切面中定義的方法所切入--> <aop:pointcut id="pointcut" expression="execution(* com.example.demo.test.TargetDemo.*(..))"/> <!--定義一個前置通知,執行的方法是切面中的beforeMethod()方法--> <aop:before pointcut-ref="pointcut" method="beforeMethod"/> <!--定義一個後置通知,執行的方法是切面中的afterMethod()方法--> <aop:after pointcut-ref="pointcut" method="afterMethod"/> </aop:aspect> </aop:config>
Java類:
// 切面類
public class AOP{
public void beforeMethod(){
System.out.println("前置通知被執行");
}
public void afterMethod(){
System.out.println("後置通知被執行");
}
}
方式三(基於註解)
// 切面類,定義前置,後置,環繞通過方法
@Aspect
public class AOP {
@Before("execution(* TargetDemo.doMyThings(..))")
public void before()
{
System.out.println("應該在之前被執行");
}
@After("execution(* TargetDemo.doMyThings(..))")
public void after()
{
System.out.println("應該在之後被執行");
}
@Around("execution(* TargetDemo.doMyThings(..))")
public void round(ProceedingJoinPoint jp) throws Throwable {
System.out.println("環繞前通知");
jp.proceed();
System.out.println("環繞後執行");
}
}
XML檔案:開啟自動aop代理
<aop:aspectj-autoproxy/>