spring AOP 之 注解 配置实现(附 Java 代码实例)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://lixuekai.blog.csdn.net/article/details/53381527

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









展开阅读全文

没有更多推荐了,返回首页