0
点赞
收藏
分享

微信扫一扫

Spring代理

兮城 2023-03-08 阅读 9


文章目录

  • ​​手动代理​​
  • ​​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();
}


举报

相关推荐

0 条评论