daily 2017 8 8 spring 的aop编程 - wtdig/study GitHub Wiki

spring 的aop编程

一、spring aop编程术语

1、连接点:目标类的方法

2、切入点:需要增强目标类的方法

3、通知:需要增强的具体功能实现,就是目标方法需要怎样增强

4、切面:将需要增强目标类的方法,进行怎样的增强,整合起来

5、织入:将切面放入需要代理的类里面,生成一个代理对象的过程

6、举例说明:小明吃早餐,上班。

目的对象:小明;连接点:吃早餐,上班;切入点:吃早餐(吃早餐进行增强,上班不进行增强,所有只有吃早餐是切入点);通知:自定义增强的方法(比如:前置通知,先付钱的方法);

这样之后,就是,小明在吃早餐这个方法之前会先去执行先付钱的方法


二、spring 内部实现aop的方法,有两种

1、一种是:采用jdk的动态代理;一种是:采用cglib的动态代理

2、spring在选择代理方式时,如果一个类有接口,那么spring优先采用jdk的动态代理去代理这个类,如果一个类没有接口,那么spring采用cglib的动态代理去代理这个类

3、因为,采用jdk的动态代理,是基于接口的动态代理,该类必须有接口才可以代理,目标对象和代理类都实现了该接口,目标对象和代理类是兄弟关系;采用cglib动态代理,是基于类的动态代理,该类无需有接口,生成的代理类是目标对象类的子类,也就是,目标对象与代理对象是父子关系


三、切面编程的框架

1、实现spring的aop的切面编程,有2个框架可以选择:一个是:采用传统的aop进行切面编程,使用的aop的aopalliance-1.0.jar和spring-aop-3.2.12.RELEASE.jar,就是aop联盟;另一个是:采用aspectj的框架进行切面编程,aspectjweaver-1.6.8.jar和spring-aspects-3.2.12.RELEASE.jar

2、区别:采用传统aop切面编程,想要进行前置、后置通知等其他的方式,必须实现相应的通知类型接口;而采用aspectj的切面编程,只需简单定义一个类就行,无需其他接口


四、切入点语法表达式

切入点表达式的语法整理如下:

1、bean(bean Id/bean name)

例如 bean(customerService) 增强customerService的bean中所有方法

2、execution(<访问修饰符>?<返回类型>空格<方法名>(<参数>)<异常>?)

例如:

execution(* cn.itcast.spring.a_jdkproxy.CustomerServiceImpl.*(..)) 增强bean对象所有方法

execution(* cn.itcast.spring..*.*(..)) 增强spring包和子包所有bean所有方法

提示:最灵活的

3、within(包.类)

例如: within(cn.itcast.spring..*) 增强spring包和子包所有bean“所有方法 ”

4、this(完整类型)/target(完整类型)

this对某一个类-(代理对象有效),target对代理对象无效(只对目标对象有效)

例如: this(cn.itcast.spring.a_jdkproxy.CustomerServiceImpl) 增强类型所有方法(对代理对象有效)

【AspectJ类型匹配的通配符】

*:匹配任何数量字符;

..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。

+:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。


五、配置步骤

1、确定目标对象

2、配置通知方法

3、配置切面:切入点的规则,引入通知


代码实例

1、springAop

1)、pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>cn.wt.springaop</groupId>
    <artifactId>springaop</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.7.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>3.2.7.RELEASE</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2)、配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="  
    http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context.xsd  
    http://www.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans.xsd  
    http://www.springframework.org/schema/tx  
    http://www.springframework.org/schema/tx/spring-tx.xsd  
    http://www.springframework.org/schema/jdbc  
    http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd  
    http://www.springframework.org/schema/cache  
    http://www.springframework.org/schema/cache/spring-cache-3.1.xsd  
    http://www.springframework.org/schema/aop  
    http://www.springframework.org/schema/aop/spring-aop.xsd  
    http://www.springframework.org/schema/util  
    http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- 目标对象 -->
    <bean id="consumerService" class="cn.wt.spring.aop.service.impl.ConsumerServiceImpl"/>
    <bean id="productService" class="cn.wt.spring.aop.cglib.service.ProductService"/>
    <!-- 通知类 -->
    <bean id="myAdvice" class="cn.wt.spring.aop.advice.MyAdvice" />
    <!-- 配置切面 -->
    <aop:config>
        <aop:pointcut expression="bean(*Service)" id="mypointcut" />
        <aop:advisor advice-ref="myAdvice" pointcut-ref="mypointcut" />
    </aop:config>
</beans>

3)、代码

package cn.wt.spring.aop.advice;

import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInvocation;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.MethodBeforeAdvice;

/**
 * @author wb-wt261136
 * @version 2017年8月15日 下午3:59:50
 */
public class MyAdvice implements MethodInterceptor {

//    @Override
//    public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
//        String name = arg0.getName();
//        System.out.println("前置方法增强了!" + name);
//    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("前置增强!");
        Object proceed = invocation.proceed();
        System.out.println("后置增强了");
        return proceed;
    }

}


package cn.wt.spring.aop.cglib.service;

/**
 * @author wb-wt261136
 * @version 2017年8月15日 下午3:57:11
 */
public class ProductService {

    public void buy() {
        System.out.println("生成者购买了商品!");
    }

    public double cost(double money) {
        System.out.println("生产者花费了:" + money + "钱!");
        return money;
    }
}

package cn.wt.spring.aop.service;

/**
 * @author wb-wt261136
 * @version 2017年8月15日 下午3:51:49
 */
public interface ConsumerService {

    public void buy();

    public double cost(double money);
}

package cn.wt.spring.aop.service.impl;

import cn.wt.spring.aop.service.ConsumerService;

/**
 * @author wb-wt261136
 * @version 2017年8月15日 下午3:53:19
 */
public class ConsumerServiceImpl implements ConsumerService {

    @Override
    public void buy() {
        System.out.println("消费者购买了商品!");
    }

    @Override
    public double cost(double money) {
        System.out.println("消费者花费了:" + money + "钱!");
        return money;
    }

}

package cn.wt.spring.aop.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.junit.runner.RunWith;
import cn.wt.spring.aop.cglib.service.ProductService;
import cn.wt.spring.aop.service.ConsumerService;

/**
 * @author wb-wt261136
 * @version 2017年8月15日 下午4:07:41
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpringAopTest {

    @Autowired
    private ConsumerService consumerService;
    @Autowired
    private ProductService  productService;

    @Test
    public void aopTest() {

        consumerService.buy();
        consumerService.cost(100);

        productService.buy();
        productService.cost(100);
    }
}

2、springAopAspectj

1)、pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>cn.wt.springaop</groupId>
    <artifactId>springaopaspectj</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.2.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.2.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>3.2.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>3.2.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>3.2.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>3.2.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>3.2.7.RELEASE</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2)、配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="  
    http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context.xsd  
    http://www.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans.xsd  
    http://www.springframework.org/schema/tx  
    http://www.springframework.org/schema/tx/spring-tx.xsd  
    http://www.springframework.org/schema/jdbc  
    http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd  
    http://www.springframework.org/schema/cache  
    http://www.springframework.org/schema/cache/spring-cache-3.1.xsd  
    http://www.springframework.org/schema/aop  
    http://www.springframework.org/schema/aop/spring-aop.xsd  
    http://www.springframework.org/schema/util  
    http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- 目标对象 -->
    <bean id="consumerService" class="cn.wt.spring.aop.service.impl.ConsumerServiceImpl" />
    <bean id="productService" class="cn.wt.spring.aop.cglib.service.ProductService" />
    <!-- 通知类 -->
    <bean id="myAdvice" class="cn.wt.spring.aop.advice.MyAdvice" />
    <!-- 配置切面 -->
    <!-- <aop:config> <aop:pointcut expression="bean(*Service)" id="mypointcut" 
        /> <aop:advisor advice-ref="myAdvice" pointcut-ref="mypointcut" /> </aop:config> -->

    <aop:config>
        <aop:pointcut expression="bean(*Service)" id="mycut" />
        <aop:aspect ref="myAdvice">
            <aop:before method="before" pointcut-ref="mycut" />
        </aop:aspect>
    </aop:config>
</beans>

3)、代码

package cn.wt.spring.aop.advice;

/**
 * @author wb-wt261136
 * @version 2017年8月15日 下午3:59:50
 */
public class MyAdvice {

    public void before() {
        System.out.println("前置通知加强");
    }
}

package cn.wt.spring.aop.cglib.service;

/**
 * @author wb-wt261136
 * @version 2017年8月15日 下午3:57:11
 */
public class ProductService {

    public void buy() {
        System.out.println("生成者购买了商品!");
    }

    public double cost(double money) {
        System.out.println("生产者花费了:" + money + "钱!");
        return money;
    }
}


package cn.wt.spring.aop.service;

/**
 * @author wb-wt261136
 * @version 2017年8月15日 下午3:51:49
 */
public interface ConsumerService {

    public void buy();

    public double cost(double money);
}

package cn.wt.spring.aop.service.impl;

import cn.wt.spring.aop.service.ConsumerService;

/**
 * @author wb-wt261136
 * @version 2017年8月15日 下午3:53:19
 */
public class ConsumerServiceImpl implements ConsumerService {

    @Override
    public void buy() {
        System.out.println("消费者购买了商品!");
    }

    @Override
    public double cost(double money) {
        System.out.println("消费者花费了:" + money + "钱!");
        return money;
    }

}

package cn.wt.spring.aop.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.junit.runner.RunWith;
import cn.wt.spring.aop.cglib.service.ProductService;
import cn.wt.spring.aop.service.ConsumerService;

/**
 * @author wb-wt261136
 * @version 2017年8月15日 下午4:07:41
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpringAopTest {

    @Autowired
    private ConsumerService consumerService;
    @Autowired
    private ProductService  productService;

    @Test
    public void aopTest() {

        consumerService.buy();
        consumerService.cost(100);

        productService.buy();
        productService.cost(100);
    }
}

⚠️ **GitHub.com Fallback** ⚠️