項目結構:
切面類:
package edu.nf.ch12.service.aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; /** * @author wangl * @date 2018/10/24 */ @Aspect //這個注解標識當前的類為一個切面 @Component //標識容器受管的Bean對象 public class UserServiceAspect { /** * 聲明一個切入點,並編寫切入點表達式 */ @Pointcut("execution(* edu.nf.ch12.service.*.*(..))") public void pointcut(){ } /** * 前置通知,指定切入點函數 * 也可在注解中自定義不同的切入點表達式 * @Before("execution(...)") * */ @Before("pointcut()") public void before(JoinPoint joinPoint){ System.out.println("前置通知..."+joinPoint.getArgs()[0]); } /** * 后置通知 */ @AfterReturning(value = "pointcut()", returning = "returnVal") public void afterReturn(String returnVal){ System.out.println("后置通知..." + returnVal); } /** * 環繞通知 */ @Around("pointcut()") public Object around(ProceedingJoinPoint pjp) throws Throwable { System.out.println("環繞通知前..."); Object returnVal = pjp.proceed(); System.out.println("環繞通知后..."); return returnVal; } /** * 異常通知 * 通過pointcut指定切入點 */ @AfterThrowing(pointcut = "pointcut()", throwing = "e") public void throwableAdvice(Throwable e){ System.out.println("異常通知..." + e.getMessage()); } /** * 最終通知 */ @After("pointcut()") public void after(){ System.out.println("最終通知..."); } }
配置類AppConfig:
package edu.nf.ch12.service.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.EnableAspectJAutoProxy; /** * @author wangl * @date 2018/10/24 */ @ComponentScan("edu.nf.ch12") //啟用包掃描 @EnableAspectJAutoProxy //啟用AspectJ注解自動配置,proxyTargetClass用於指定是否強制使用cglib代理 public class AppConfig { }
接口類:
package edu.nf.ch12.service; /** * @author wangl * @date 2018/10/24 */ public interface UserService { /** * 查詢用戶 * @param uid * @return */ String getUserNameById(String uid); }
接口實現類:
package edu.nf.ch12.service.impl; import edu.nf.ch12.service.UserService; import org.springframework.stereotype.Service; /** * @author wangl * @date 2018/10/24 */ @Service("userService") public class UserServiceImpl implements UserService { @Override public String getUserNameById(String uid) { System.out.println("查詢用戶..."+uid); return "user1"; } }
程序測試類:
package edu.nf.ch12.test; import edu.nf.ch12.service.UserService; import edu.nf.ch12.service.config.AppConfig; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author wangl * @date 2018/10/24 */ public class UserServiceTest { @Test public void testGetUser(){ //ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); UserService service = context.getBean("userService", UserService.class); service.getUserNameById("1001"); } }
如果半注解半配置文件實現的話, new ClassPathXmlApplicationContext("applicationContext.xml");實例 然后再配置一個xml
applicationContext:
<?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: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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 啟用包掃描 --> <context:component-scan base-package="edu.nf.ch12"/> <!-- 啟用AspectJ注解自動配置,proxy-target-class是否強制使用cglib動態代理,true表示強制--> <aop:aspectj-autoproxy/> </beans>
運行結果: