文章目录
- 手动代理
- JDK动态代理
- 目标类
- 切面类
- 工厂类
- 测试
- cglib增强字节码
- 目标类
- 工厂类
- 测试
- Spring半自动代理
- maven中配置相应jar包
- 编写目标类和切面类
- Spring xml文件配置
- 测试
- Spring AOP全自动编程
- maven中配置相应jar包
- 编写目标类和切面类
- Spring xml文件配置
- 测试
手动代理
JDK动态代理
目标类
package org.ccit.com.service;
/**
* @program: Spring02
* @description
* @author: LIANG
* @create: 2021-04-26 11:58
**/
public interface IUserService {
public void addUser();
public void updateUser();
public void deleteUser();
}
package org.ccit.com.service;
/**
* @program: Spring02
* @description
* @author: LIANG
* @create: 2021-04-26 11:59
**/
public class UserServiceImpl implements IUserService {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void updateUser() {
System.out.println("更新用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
切面类
package org.ccit.com.aspect;
/**
* @program: Spring02
* @description
* @author: LIANG
* @create: 2021-04-26 12:08
**/
public class MyAspect {
public void before(){
System.out.println("开启事务");
}
public void after(){
System.out.println("提交事务");
}
}
工厂类
package org.ccit.com.service;
import org.ccit.com.aspect.MyAspect;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @program: Spring02
* @description
* @author: LIANG
* @create: 2021-04-26 12:13
**/
public class UserServiceBeanFactory {
public static IUserService createUserService(){
//目标类
final IUserService userService=new UserServiceImpl();
//切面类
final MyAspect aspect=new MyAspect();
//代理类 将目标类和切面类结合
/*
* public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
* 参数1,类加载器 一般写当前类
* 参数2,代理类所需要实现的接口
* 参数3,处理类 一般写匿名类*/
IUserService proxyService=(IUserService) Proxy.newProxyInstance(UserServiceBeanFactory.class.getClassLoader(), userService.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
aspect.before();
//放行
Object obj = method.invoke(userService, args);
aspect.after();
return obj;
}
});
return proxyService;
}
}
测试
@Test
public void test01(){
//jdk
IUserService userService = MyBeanFactory.createUserService();
userService.addUser();
}
cglib增强字节码
有接口无接口都可使用
目标类
public class StudentService {
public void addStudent() {
System.out.println("添加学生");
}
public void updateStudent() {
System.out.println("更新学生");
}
public void deleteStudent() {
System.out.println("删除用户");
}
}
### 切面类
```java
public class MyAspect {
public void before(){
System.out.println("开启事务");
}
public void after(){
System.out.println("提交事务");
}
}
工厂类
/**
* @Description: cglib实现代理(创建目标类的子类 通过继承的方式对目标类进行增强)
* @params: []
* @return: org.ccit.com.service.IUserService
* @Author: LIANG
* @Date: 2021/4/26 21:18
*/
public static StudentService createStudentService(){
//目标类
StudentService studentService = new StudentService();
//切面类
MyAspect aspect = new MyAspect();
//创建增强对象
Enhancer enhancer = new Enhancer();
//设置父类 目标类
enhancer.setSuperclass(studentService.getClass());
//设置回调
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
aspect.before();
//放行
Object retObj = method.invoke(studentService, objects);
//methodProxy.invokeSuper(o,objects);
aspect.after();
return retObj;
}
});
StudentService serviceProxy= (StudentService) enhancer.create();
return serviceProxy;
}
测试
@Test
public void test02(){
//cglib
StudentService studentService = MyBeanFactory.createStudentService();
studentService.addStudent();
}
Spring半自动代理
maven中配置相应jar包
<!-- aop联盟-->
<dependency>
<groupId>org.aopalliance</groupId>
<artifactId>com.springsource.org.aopalliance</artifactId>
<version>1.0.0</version>
</dependency>
<!-- aop实现-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
编写目标类和切面类
package org.ccit.com.service;
/**
* @program: Spring02
* @description
* @author: LIANG
* @create: 2021-04-26 11:59
**/
public class UserServiceImpl implements IUserService {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void updateUser() {
System.out.println("更新用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
package org.ccit.com.aspect;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.stereotype.Component;
/**
* @program: Spring02
* @description
* @author: LIANG
* @create: 2021-04-26 12:08
**/
public class MyAspect01 implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
/**
* @Description: 拦截方法
* @params: [invocation]
* @return: java.lang.Object
* @Author: LIANG
* @Date: 2021/4/29 7:38
*/
System.out.println("开启事务");
//放行
Object retObj = invocation.proceed();
System.out.println("拦截");
System.out.println("结束事务");
return retObj;
}
}
Spring 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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="userService" class="org.ccit.com.service.UserServiceImpl"></bean>
<bean id="myAspect" class="org.ccit.com.aspect.MyAspect01"></bean>
<!-- 代理工厂-->
<bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 配置接口 目标对象 切面类 -->
<!-- 如股只是一个接口 就写value 如果是多个接口就写list-->
<property name="interfaces" value="org.ccit.com.service.IUserService"></property>
<property name="target" ref="userService"></property>
<property name="interceptorNames" value="myAspect"></property>
<!-- 默认情况下 Spring 的AOP生成的代理是jdk的Proxy实现的-->
<!-- 配置使用cglib生成代理 optimize 优化-->
<property name="optimize" value="true"></property>
</bean>
</beans>
测试
@Test
public void method01(){
//获取Spring容器中代理对象
ApplicationContext context = new ClassPathXmlApplicationContext("bean01.xml");
IUserService userService = (IUserService)context.getBean("serviceProxy");
userService.deleteUser();
}
Spring AOP全自动编程
maven中配置相应jar包
<!-- AOP全自动编程需要导入的aspectj.weaver-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
编写目标类和切面类
同半自动编程
Spring xml文件配置
<!-- 全自动代理实现
添加aop约束
将切入点和通知结合
-->
<!-- proxy-target-class: true默认使用cglib实现代理-->
<aop:config proxy-target-class="true">
<!-- 切入点 事务配置和日志记录 -->
<!--expression: 表达式 每个servise方法前后都开启事务和关闭事务
execution(* org.ccit.com.service.*.*(..)) 代表包内所有类(业务类)所有方法 (..)表示不同参数
-->
<aop:pointcut id="myPointcut" expression="execution(* org.ccit.com.service.*.*(..))"/>
<!--通知关联切入点 通知可以理解为切面类-->
<aop:advisor advice-ref="myAspect" pointcut-ref="myPointcut"></aop:advisor>
</aop:config>
测试
直接从容器中获取对象
@Test
public void method01(){
//获取Spring容器中代理对象
ApplicationContext context = new ClassPathXmlApplicationContext("bean01.xml");
IUserService userService = (IUserService)context.getBean("userService");
userService.deleteUser();
}