注解方式配置aop
一、编码前准备工作
1. 建项目需要的包和类,如下图所示:
其中aspect里放的是两种方式定义的切面,annotation是注释方式,xml是xml方式
下面两种配置文件也是同样的
2. 在pom.xml内添加需要的依赖包
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.9</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency> </dependencies>
二、Dao接口和类代码实现
1. UserDao
public interface
UserDao {
public BooleantestUserDao();
}
2. UserDaoImpl
我这里使用自动扫描的方式注入bean,所以给下面类加入注解
@Component("userDao")
public class UserDaoImpl implements UserDao { public Boolean testUserDao() { System.out.println("testUserDao!!!!!"); return true; } }
三、切面类实现
1. 定义切面类
@Aspect
2. 加自动扫描的注解
@Component("userDao")
3. 定义切入点
@Pointcut("execution(* com.neusoft.spring.aop.demo.dao.impl.UserDaoImpl.*(..))") public void getPointCut(){}
Expression说明:
第一个*号,表示任意返回值类型
第二个*号,表示任意方法名(根据自己的判断,因为我这里已经具体到类了,所以是方法名)
(..)表示方法可以有0个或多个参数
4. 定义通知
1) 前置通知
@Before("getPointCut()") public void doBefore(){ System.out.println("前置通知!!!!"); }
2) 后置通知
@AfterReturning("getPointCut()") public void doAfterReturn(){ System.out.println("后置通知!!!"); }
3) 最终通知
@After("getPointCut()") public void doFinallyReturn(){ System.out.println("最终通知!!!"); }
4) 异常通知
@AfterThrowing("getPointCut()") public void doThrowing(){ System.out.println("异常通知!!!!"); }
5) 环绕通知
@Around("getPointCut()") public Object doArround(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("环绕通知----开始"); Object o = pjp.proceed(); System.out.println("环绕通知----结束"); return o; }
ProceedingJoinPoint 表示正在执行的方法
Pjp.procees();让该方法执行
四、ApplicationContext配置
1. 添加命名空间
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
2. 自动扫描组件
<context:component-scan base-package="com.neusoft.spring.aop.demo.dao"/> <context:component-scan base-package="com.neusoft.spring.aop.demo.aspect"/>
3. 自动代理
<aop:aspectj-autoproxy proxy-target-class="true"/>
五、测试
@Test public void testAnnotation(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-annotation.xml"); UserDao userDao = context.getBean("userDao",UserDao.class); userDao.testUserDao(); }
六、结果
因为这里没有异常,所以没有异常通知。
七、异常通知
1. 让实现类里抛出异常
@Component("userDao") public class UserDaoImpl implements UserDao { public void testUserDao() { System.out.println("testUserDao!!!!!"); throw new RuntimeException("异常"); } }
2. 查看结果