Spring对AOP的实现提供了很好的支持。下面我们就使用Spring的注解来完成AOP做一个例子。
首先,为了使用Spring的AOP注解功能,必须导入如下几个包。aspectjrt.jar,aspectjweaver.jar,cglib-nodep.jar.
1、实体bean
public class Person { private Long id; private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
2、接口类
public interface PersonService { public void save(Person person); public void update(Person person); public Person getByIdPerson(Long id); public void delete(Long id); }
3、实现类
public class PersonServiceImpl implements PersonService{ Map<Long, Person> maps = new HashMap<Long, Person>(); @Override public void save(Person person) { System.out.println("***执行save方法***"); maps.put(person.getId(), person); } @Override public void update(Person person) { System.out.println("***执行update()方法***"); maps.remove(person.getId()); maps.put(person.getId(), person); } @Override public Person getByIdPerson(Long id) { System.out.println("***执行getByIdPerson()方法***"); return maps.get(id); } @Override public void delete(Long id) { System.out.println("***执行delete()方法***"); maps.remove(id); } }
4、使用Spring注解方式对这个Bean进行方法拦截
@Aspect public class MyInterceptor { @Pointcut("execution(* cn.tzz.aop.annotation.service.impl..*.*(..))") private void anyMethod(){}//定义切点 @Before("anyMethod() && args(person)") public void doAccessCheck(Person person){ System.out.println(person.getName()); System.out.println("前置通知"); } @AfterReturning("anyMethod()") public void doAfter(){ System.out.println("后置通知"); } @After("anyMethod()") public void after(){ System.out.println("最终通知"); } @AfterThrowing("anyMethod()") public void doAfterThrow(){ System.out.println("异常通知"); } @Around("anyMethod()") public Object doBasicProfiling(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{ System.out.println("进入环绕通知"); Object object = proceedingJoinPoint.proceed();//执行该方法 System.out.println("退出方法"); return object; } }
@Pointcut("execution(* cn.tzz.aop.annotation.service.impl..*.*(..))")
上述是定义方法切入点,execution为执行的意思,*代表任意返回值,然后是包名,.*意思是包下面的所有子包,(..)代表各种方法.
5、在Spring的配置文件中配置Bean,需要打开AOP命名空间
<?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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <context:annotation-config /> <context:component-scan base-package="cn.tzz.aop.annotation" /> <aop:aspectj-autoproxy proxy-target-class="true" /> <bean id="personService" class="cn.tzz.aop.annotation.service.impl.PersonServiceImpl"></bean> <bean id="myInterceptor" class="cn.tzz.aop.annotation.MyInterceptor"></bean> </beans>
6、测试
public class TestAop { private static ApplicationContext ctx = null; private static PersonService personService = null; static{ ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); personService = (PersonService)ctx.getBean("personService"); } public void testSave(){ Person person = new Person(); person.setId(1L); person.setName("abc"); personService.save(person); } public void testGetByIdPerson(){ Person p = personService.getByIdPerson(1L); System.out.println(p.getId()+"---"+p.getName()); } public void testUpdate(){ Person person = new Person(); person.setId(1L); person.setName("abc_1"); personService.update(person); } public void testDelete(){ personService.delete(1L); } @Test public void testInteceptor(){ testSave(); // testGetByIdPerson(); // testUpdate(); // testGetByIdPerson(); // testDelete(); // testGetByIdPerson(); } }
7、测试结果
abc 前置通知 进入环绕通知 ***执行save方法*** 后置通知 退出方法 最终通知