daily 2017 8 8 spring 的aop编程 - wtdig/study GitHub Wiki
1、连接点:目标类的方法
2、切入点:需要增强目标类的方法
3、通知:需要增强的具体功能实现,就是目标方法需要怎样增强
4、切面:将需要增强目标类的方法,进行怎样的增强,整合起来
5、织入:将切面放入需要代理的类里面,生成一个代理对象的过程
6、举例说明:小明吃早餐,上班。
目的对象:小明;连接点:吃早餐,上班;切入点:吃早餐(吃早餐进行增强,上班不进行增强,所有只有吃早餐是切入点);通知:自定义增强的方法(比如:前置通知,先付钱的方法);
这样之后,就是,小明在吃早餐这个方法之前会先去执行先付钱的方法
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)、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);
}
}
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);
}
}