导入类扫描的注解解析器
命名空间: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










发布评论
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

Java动态代理模式jdk和cglib的2种实现以及二者的区别(AOP面向切面的前奏)知识解答
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。