spring详解之注解的方式配置AOP(六)
1实现开启注解模式,在applicationContext.xml文件中配置
<aop:aspectj-autoproxy></aop:aspectj-autoproxy> |
2注解切面
在通知上面添加一个注解@Aspect
@Aspect //切面 |
在通知的方法上添加切点有五种方式
@Before(表达式)
@Pointcut(),@Before(),@AfterReturning(),@Around(),
@After(),@AfterThrowing
书写表达方式有两种
①直接写
@AfterThrowing("execution(* cn.hd.springProxyAnnotation..impl.*ServiceImpl.*(..)) |
②配置一个切点,调用类的方法获取切点
@Pointcut("execution(* cn.hd.springProxyAnnotation..impl.*ServiceImpl.*(..))") |
下面是完整代码
applicationContext.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: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="cn.hd.springProxyAnnotation"></context:component-scan> <!--开启注解模式--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
StudentService借口
public interface StudentService { void add(); void delete(); void update(); void find(); }
StudentService的实现接口类StudentServiceImpl
@Service("studentService") public class StudentServiceImpl implements StudentService { @Override public void add() { System.out.println("添加学生信息"); } @Override public void delete() { System.out.println("删除学生信息"); } @Override public void update() { System.out.println("修改学生信息"); } @Override public void find() { System.out.println("查找学生信息"); } }
通知类(bean类)
@Component("myAdvice") @Aspect public class MyAdvice { @Pointcut("execution( * cn.hd.springProxyAnnotation..impl.*ServiceImpl.*(..))") public void ps(){} //@Pointcut("execution( * cn.hd.springProxy..impl.*ServiceImpl.*(..))") @Before("MyAdvice.ps()") public void before(){ System.out.println("在目标对象方法执行前调用"); } //@Before("execution( * cn.hd.springProxy..impl.*ServiceImpl.*(..))") @AfterReturning("MyAdvice.ps()") public void afterReturning(){ System.out.println("如果目标对象没有异常就会执行"); } // @Around("execution( * cn.hd.springProxy..impl.*ServiceImpl.*(..))") @Around("MyAdvice.ps()") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("环绕前在目标对象前调用"); Object proceed = proceedingJoinPoint.proceed(); System.out.println("环绕后在目标对象后调用"); return proceed; } // @After("execution( * cn.hd.springProxy..impl.*ServiceImpl.*(..))") @After("MyAdvice.ps()") public void after(){ System.out.println("目标方法后调用,不管有没有异常"); } //@AfterThrowing("execution( * cn.hd.springProxy..impl.*ServiceImpl.*(..))") @AfterThrowing("MyAdvice.ps()") public void throwException(){ System.out.println("目标对象出现异常调用调用该方法"); }
}
bean类有两种方式,第一种就是注释的那种,但是那种方式感到代码重复,所以就有第二种方式
就是声明一个方法,并在方法的上面添加注解,然后在每个方法上添加注解,并调用上面的方法注解,
这样就显得代码就比较少了,代码量大大滴减少了,这样有利于提高开发效率。
最后进行测试:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:cn/hd/springProxyAnnotation/applicationContext.xml") public class Demo { @Resource(name = "studentService") private StudentService studentService; @Test public void fun(){ studentService.add(); studentService.delete(); studentService.find(); studentService.update(); } }
出现上面的打印结果说明你的注解添加成功了