首先咱們寫個UserService接口和它的實現類java
public interface UserService { public void add(); } public class UserServiceImpl implements UserService { @Override public void add() { System.out.println("add user"); } }
在applicationConte.xml導入命名空間。先搞切入點,再在切入點把Log.java切入進去。spring
<bean id="userService" class="com.zhou.service.UserServiceImpl"/> <bean id="log" class="com.zhou.log.Log"/> <bean id="afterLog" class="com.zhou.log.AfterLog"/> <!-- 方式一:執行原生SpringApi接口--> <aop:config> <!-- 切入點 execution(第一個「*」表示返回值的類型任意 「com.zhou.service.UserServiceImpl」要執行的位置 「.*」 表明這個類下的全部方法 「..」表明能夠有任意參數) --> <aop:pointcut id="pointcut" expression="execution(* com.zhou.service.UserServiceImpl.*(..))"/> <!-- 執行環繞! 把log這個類切入到「* com.zhou.service.UserServiceImpl.*(..)」方法上面--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config>
Log.java: public class Log implements MethodBeforeAdvice { // method:方法 //objects:參數 //o:對象 @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println(o.getClass().getName()+"的"+method.getName()+"被執行了");//某某對象的方法被執行了 } } AfterLog.java: package com.zhou.log; public class AfterLog implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[] objects, Object target) throws Throwable { System.out.println("執行了"+method.getName()+"返回的結果爲"+returnValue); } }
public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //PS:動態代理的是接口 UserService userService = (UserService) context.getBean("userService"); userService.add(); } //報錯了 由於沒導入aspect依賴 }
com.zhou.service.UserServiceImpl的add被執行了
add user
執行了add返回的結果爲nullexpress
先寫一個簡單MyPointCut類api
public class MyPointCut { public void before(){ System.out.println("我在方法執行前面"); } public void after(){ System.out.println("我在方法執行後面"); } }
另外一種方式配置applicationConte.xmlapp
<!--方式二:自定義類--> <bean id="diyPointCut" class="com.zhou.own.MyPointCut"/> <aop:config> <!--自定義切面 --> <aop:aspect ref="diyPointCut"> <!--切入點--> <aop:pointcut id="pointcut" expression="execution(* com.zhou.service.UserServiceImpl.*(..))"/> <!-- 通知--> <aop:before method="before" pointcut-ref="pointcut"/> <aop:after method="after" pointcut-ref="pointcut"/> </aop:aspect> </aop:config>
測試一下ide
public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) context.getBean("userService"); userService.add(); } }
輸出結果:測試
我在方法執行前面
add user
我在方法執行後面代理
execution表達式:code
<aop:pointcut id="pointcut" expression="execution(* com.zhou.service.UserServiceImpl.*(..))"/>
* | 表示返回值的類型任意 |
---|---|
com.zhou.service.UserServiceImpl | 橫切的業務類路徑 |
.* | 表明這個類下的全部方法 |
(..) | ()表明參數,兩個點表明能夠有任意參數 |
MyPointCut.javaxml
@Aspect public class AnnotationPointCut { @Before("execution(* com.zhou.service.UserServiceImpl.*(..))") public void before() { System.out.println("我在方法執行前面"); } @After("execution(* com.zhou.service.UserServiceImpl.*(..))") public void after() { System.out.println("我在方法執行後面"); }
關於環繞(@Around)
//在環繞加強中 咱們能夠給定一個參數 表明咱們要處理切入的點 JointPoint:與切入點匹配的執行點 @Around("execution(* com.zhou.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("環繞前"); Object proceed = joinPoint.proceed();//執行方法 System.out.println("環繞後"); //Signature signature = joinPoint.getSignature(); //System.out.println("signature:" + signature.toString()); } }
配置文件
<!-- 方式三--> <bean id="annotationPointCut" class="com.zhou.own.AnnotationPointCut"/> <!-- 開啓註解支持--> <aop:aspectj-autoproxy/>
輸出結果:看看順序= =
環繞前 我在方法執行前面 add user 我在方法執行後面 環繞後