spring,静态代理和动态代理(jdk和cglib方式)示例
2020-01-15 11:53
239 查看
基于maven项目,pom.xml的配置:
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.1.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.1.RELEASE</version> <scope>test</scope> </dependency> </dependencies>
实体类的代码:此处只是模拟数据库插入数据,但是并没有真正的插入数据。故实体类比较简单。
package com.bean; public class Employee { }
dao层:
EmployeeDao.java
package com.dao; import com.hpeu.bean.Employee; public interface EmployeeDao { public void save(Employee employee); public void update(Employee employee); }
dao实现层:
EmployeeDaoImpl.java
package com.dao; import com.bean.Employee; public class EmployeeDaoImpl implements EmployeeDao { @Override public void save(Employee employee) { System.out.println("保存员工"); } @Override public void update(Employee employee) { System.out.println("修改员工"); } }
service层:
EmployeeService.java
package com.service; import com.bean.Employee; public interface EmployeeService { public void save(Employee emp); public void update(Employee emp); public Employee getEmployeeById(Integer id); }
service实现层:
EmployeeServiceImpl.java
package com.service.impl; import com.bean.Employee; import com.dao.EmployeeDao; import com.service.EmployeeService; public class EmployeeServiceImpl implements EmployeeService { private EmployeeDao dao; public void setDao(EmployeeDao dao) { this.dao = dao; } @Override public void save(Employee emp) { //System.out.println("开启事务"); //try { dao.save(emp); //System.out.println("提交事务"); //} catch (Exception e) { //e.printStackTrace(); //System.out.println("回滚事务"); //} finally { //System.out.println("释放资源"); //}//此处太繁琐了,需要封装成一个类 } @Override public void update(Employee emp) { dao.update(emp); throw new RuntimeException("出错了。。。。"); } }
模拟事务管理器:
TransactionManager.java
package com.service.impl; // 模拟事务管理器 public class TransactionManager { public void begin() { System.out.println("开启事务"); } public void commit() { System.out.println("提交事务"); } public void rollback() { System.out.println("回滚事务"); } }
静态代理层:
StaticProxyService。java
package com.proxy; import com.bean.Employee; import com.service.EmployeeService; import com.service.impl.TransactionManager; /** * 静态代理类 * 静态代理类需要有真实对象的引用,因代理对象中的核心方法还是真实对象来完成。 */ public class StaticProxyService { private EmployeeService target; // 真实对象 private TransactionManager txManager; // 代理对象 public void setTarget(EmployeeService target) { this.target = target; } public void setTxManager(TransactionManager txManager) { this.txManager = txManager; } public void save(Employee emp) { txManager.begin(); try { target.save(emp); txManager.commit(); } catch (Exception e) { e.printStackTrace(); txManager.rollback(); } } public void update(Employee emp) { txManager.begin(); try { target.update(emp); txManager.commit(); } catch (Exception e) { txManager.rollback(); System.out.println(e.getMessage()); } } }
jdk动态代理层:
JdkDyniProxy.java
package com.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.service.impl.TransactionManager; /** * JDK动态代理 * 前提条件: * 真实对象(被代理对象)必须实现至少一个接口。 * * 实现方法: * 需要使用java.lang.reflect.Proxy类,然后使用该类中的newProxyInstantce()方法来 * 实例化代理对象。 * 同时,还需要有一个实现了java.lang.reflcet.InvocationHandler接口的类。因为 * 在执行代理对象时,系统自动会调用被代理对象的invoke方法。 */ public class JdkDyniProxy implements InvocationHandler { // 定义被代理对象 private Object target; private TransactionManager txManager; // 事务管理器 public void setTarget(Object target) { this.target = target; } public void setTxManager(TransactionManager txManager) { this.txManager = txManager; } /* public JdkDyniProxy(Object target) { this.target = target; } */ // 通过动态代理的方式来创建真实对象 public Object create() { /** * 参数说明: * ClassLoader loader:被代理对象(真实对象)的类装载器 * Class<?>[] interfaces:被代理对象实现的接口类的数组 * InvocationHandler h:实现了InvocationHandler的对象 */ return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } /** * proxy:代理对象 * method:被执行的真实对象中的方法名称 * args:被执行的真实对象中方法的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; txManager.begin(); try { System.out.println("-------" + method.getName()); result = method.invoke(target, args); txManager.commit(); } catch (Exception e) { txManager.rollback(); System.out.println(e.getMessage()); } return result; } }
cglib动态代理
CGLIBDynamicProxy.java
package com.proxy; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.InvocationHandler; import com.service.impl.TransactionManager; /** * 使用CGLIB实现动态代理 * 从Spring5.X开始,CGLIB已经被纳入到官方spring-core.jar包中,以之前的版本中 * 需要引入cglib的jar文件才能使用。 * cglib实现的动态代理的对象不需要实现接口。 */ public class CGLIBDynamicProxy implements InvocationHandler { private Object target; // 被代理对象(真实对象) private TransactionManager txManager; public void setTarget(Object target) { this.target = target; } public void setTxManager(TransactionManager txManager) { this.txManager = txManager; } // 创建代理对象 public Object create() { Enhancer enhancer = new Enhancer(); // 设置被代理对象的父类 enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); // 创建代理对象 } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String name = method.getName(); if (name.startsWith("get") || name.startsWith("find")) { return method.invoke(target, args); } Object result = null; txManager.begin(); try { System.out.println("=======" + name); result = method.invoke(target, args); txManager.commit(); } catch (Exception e) { txManager.rollback(); System.out.println(e.getMessage()); } return result; } }
spring配置类:
beans.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" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="txManager" class="com.service.impl.TransactionManager"/> <bean id="employeeDao" class="com.dao.EmployeeDaoImpl" /> <!-- 配置静态代理 --> <bean id="staticProxy" class="com.proxy.StaticProxyService"> <property name="txManager" ref="txManager" /><!--ref表示对另一个类的引用 --> <property name="target"> <bean class="com.service.impl.EmployeeServiceImpl"> <property name="dao" ref="employeeDao"/> </bean> </property> </bean> <!-- 配置JDK动态代理 --> <bean id="jdkDyniProxy" class="com.proxy.JdkDyniProxy"> <property name="target"> <bean class="com.service.impl.EmployeeServiceImpl"> <property name="dao" ref="employeeDao" /> </bean> </property> <property name="txManager" ref="txManager" /> </bean> <!-- 配置CGLIB动态代理 --> <bean id="cglibProxy" class="com.hpeu.proxy.CGLIBDynamicProxy"> <property name="target"> <bean class="com.hpeu.service.impl.EmployeeServiceImpl"> <property name="dao" ref="employeeDao" /> </bean> </property> <property name="txManager" ref="txManager" /> </bean> </beans>
Jdk动态代理测试类
JdkDyniProxyTest.java
package com.test.dyni.proxy; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import com.bean.Employee; import com.proxy.JdkDyniProxy; import com.service.EmployeeService; /** * Jdk动态代理测试类 */ @RunWith(SpringRunner.class) @ContextConfiguration("classpath:beans.xml") public class JdkDyniProxyTest { @Autowired private JdkDyniProxy jdkDyniProxy; @Test public void testSave() { EmployeeService obj = (EmployeeService) jdkDyniProxy.create(); obj.save(new Employee()); //System.out.println(obj); } @Test public void testUpdate() { EmployeeService obj = (EmployeeService) jdkDyniProxy.create(); obj.update(new Employee()); } /* @Test public void testXx() { EmployeeService obj = (EmployeeService) new JdkDyniProxy(new EmployeeServiceImpl()).create(); obj.update(new Employee()); } */ }
cglib动态代理测试类
CGLIBDynamicProxyTest.java
package com.test.dyni.proxy; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import com.bean.Employee; import com.proxy.CGLIBDynamicProxy; import com.service.EmployeeService; // CGLIB动态代理测试类 @RunWith(SpringRunner.class) @ContextConfiguration("classpath:beans.xml") public class CGLIBDynamicProxyTest { @Autowired private CGLIBDynamicProxy cglibDyniProxy; @Test public void testSave() { EmployeeService obj = (EmployeeService) cglibDyniProxy.create(); String name = obj.getClass().getName(); System.out.println(name); obj.save(new Employee()); } @Test public void testUpdate() { EmployeeService obj = (EmployeeService) cglibDyniProxy.create(); obj.update(new Employee()); } @Test public void testXx() { EmployeeService obj = (EmployeeService) cglibDyniProxy.create(); obj.getEmployeeById(2); } }
静态代理测试类
ProxyStaticTest.java
package com.test.statics.proxy; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import com.bean.Employee; import com.proxy.StaticProxyService; // 静态代理测试类 @RunWith(SpringRunner.class) @ContextConfiguration("classpath:beans.xml") public class ProxyStaticTest { @Autowired private StaticProxyService serviceProxy; @Test public void testSave() { serviceProxy.save(new Employee()); } @Test public void testUpdate() { serviceProxy.update(new Employee()); } }
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 【Spring AOP】【AspectJ】【CGLIB】【JDK动态代理】【JDK静态代理】区别
- Spring学习总结——静态代理、JDK与CGLIB动态代理、AOP+IoC
- spring(AOP)静态代理、JDK动态代理、cglib实现代理
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
- Spring中AOP实现的两种方式之JDK和cglib的动态代理
- Spring中AOP实现的两种方式之JDK和cglib的动态代理
- Spring 静态代理、jdk与cglib动态代理 spring aop+ioc
- Spring AOP 代理实现的两种方式: JDK动态代理 和 Cglib框架动态代理
- 详解Spring的两种代理方式:JDK动态代理和CGLIB动态代理
- Spring系列之 (十一):AOP实现方式:动态代理的两个方式(JDK和Cglib)
- Spring的两种代理方式:JDK动态代理和CGLIB动态代理
- Spring的两种代理方式:JDK动态代理和CGLIB动态代理
- spring02 注解方式实现MVC、spring的继承、代理模式(静/动) :jdk动态代理,cglib动态代理
- 静态代理、JDK动态代理、CGLIB动态代理、Spring实现AOP、IOC+AOP
- 浅析Spring AOP源码(十三) jdk的动态代理和cglib的代理
- Java探索之——动态代理(JDK和CGlib方式)
- Java静态代理与动态代理(JDK、CGLIB实现)
- Spring中AOP的两种代理方式(Java动态代理和CGLIB代理-转载