导入类扫描的注解解析器
命名空间:xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
引号添加这2个url
xml配置文件如下配置:<context:component-scan base-package="com.lxk.spring.aop.annotation"/>
导入springAOP的注解解析器
命名空间:xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
引号添加这2个url
xml配置文件如下配置:<aop:aspectj-autoproxy/>
上面的2个解析器的前后顺序不分先后。
接口类,目标接口
package com.lxk.spring.aop.annotation;
import java.util.List;
public interface PersonDao {
void deletePerson();
List<Person> getPerson() throws Exception;
void savePerson();
void updatePerson();
}
package com.lxk.spring.aop.annotation;
import com.google.common.collect.Lists;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Created by lxk on 2016/11/28
*/
@Repository(value = "personDaoImpl")
public class PersonDaoImpl implements PersonDao {
public void deletePerson() {
System.out.println("delete perosn");
}
public List<Person> getPerson() throws Exception {
List<Person> personList = Lists.newArrayList();
Person person1 = new Person();
person1.setPid(1L);
person1.setPname("person1");
//int a = 1 / 0;
System.out.println("get person");
personList.add(person1);
Person person2 = new Person();
person2.setPid(2L);
person2.setPname("person2");
personList.add(person2);
return personList;
}
public void savePerson() {
System.out.println("delete perosn");
}
public void updatePerson() {
System.out.println("delete perosn");
}
}
package com.lxk.spring.aop.annotation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* 切面类
* <p>
* Created by lxk on 2016/11/28
*/
@Aspect
@Component(value = "transaction")
public class Transaction {
@Pointcut("execution(* com.lxk.spring.aop.annotation.PersonDaoImpl.*(..))")
private void aa() {
}//切入点签名
/**
* 前置通知
*/
@Before("aa()")
public void beforeMethod() {
System.out.println("before method");
}
/**
* 后置通知
*/
@AfterReturning(value = "aa()", returning = "val")
public void afterMethod(JoinPoint joinPoint, Object val) {
List<Person> personList = (ArrayList<Person>) val;
if (personList != null && !personList.isEmpty()) {
for (Person person : personList) {
System.out.println(person.getPname());
}
}
System.out.println("after method");
}
/**
* 最终通知
*/
@After("aa()")
public void finalMethod(JoinPoint joinPoint) {
joinPoint.getArgs();
System.out.println("final method");
}
/**
* 环绕通知
*/
@Around("aa()")
public Object aroundMethod(ProceedingJoinPoint joinPoint) {
Object obj = null;
try {
obj = joinPoint.proceed();
} catch (Throwable e) {
System.out.println(e.getMessage());
}
System.out.println("around method");
return obj;
}
/**
* 异常通知
*/
@AfterThrowing(value = "aa()", throwing = "ex")
public void throwingMethod(Throwable ex) {
System.out.println(ex.getMessage());
}
}
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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<aop:aspectj-autoproxy/>
<context:component-scan base-package="com.lxk.spring.aop.annotation"/>
</beans>
测试和model文件
package com.lxk.spring.aop.annotation;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by lxk on 2016/11/28
*/
public class AOPAnnotationTest {
@Test
public void test() throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("com/lxk/spring/aop/annotation/applicationContext.xml");
PersonDao personDao = (PersonDao) context.getBean("personDaoImpl");
personDao.getPerson();
//List<Person> personList = personDao.getPerson("sss");
//System.out.println(personList.size());
}
}
package com.lxk.spring.aop.annotation;
/**
* Created by lxk on 2016/11/28
*/
public class Person {
private Long pid;
private String pname;
public Long getPid() {
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
}
@Component(value="transaction")
解释:就是spring注解里面的注解,泛指,只是没有像@Service、@Controller 一样,具有特殊意义。
这个注解就是把切面类,纳入到spring容器管理,相当于。
@Component=bean id="transaction" class="..Transaction",这个写法。
@Aspect
此注解的作用:标识这个类就是切面。
@Aspect相当于xml文件中的aop配置标签:<aop:config> </aop:config>
然后切面里面,就有对应的切入点,通知等等。
@Pointcut
此注解的作用:标注一个切入点
此注解不能单独存在,必须依附在切面
一个切入点声明有两个部分:一个包含名字和任意参数的签名,还有一个切入点表达式,该表达式决定了我们关注那个方法的执行。
作为切入点签名的方法必须返回void 类型
@Pointcut("execution(* com.lxk.spring.aop.annotation.PersonDaoImpl.*(..))")
private void aa(){}//切入点签名
相当于如下:在xml配置切入点。
<aop:pointcut expression="execution(* cn.itcast.spring0401.aop.annotation.PersonDaoImpl.*(..))" id="aa()"/>
然后现在切入点就是这个aa(),方法啦。
看这个实现原理,spring容器有如下几次扫描过程。
第一次,解析xml配置文件解析到类扫描的注解解析器,会在base-package指定的包及子包中扫描所有的类看类上是否有@Compontent,@Service,@Controller,@Repository注解,如果有,则spring容器创建该类的实例
第二次,解析到aop的注解解析器,会在纳入spring管理的bean中,看哪个类上面是否有@Aspect注解
第三次,在有@Aspect注解的类的所有方法中查找@Pointcut,就会找到切入点表达式,根据切入点表达式,在纳入spring范围的bean内查找,看哪个bean符合切入点表达式,如果符合则创建代理对象
当客户端访问某一个bean时,如果该bean有代理对象,则返回代理对象,否则返回该bean的对象
最后总结:
关于测试使用的jar包,如下,注意带1.7的aop相关的才是符合jdk1.7.
链接:http://pan.baidu.com/s/1c1M2NpY 密码:kted