spring5整理:(五)JDK动态代理-模拟事务

15 篇文章 0 订阅

JDK动态代理API分析:(必须要求真实对象是有接口)

1.java.lang.reflect.Proxy类:java动态代理机制生成的所有动态代理类的父类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象.

  1)主要方法:

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler handler)

  2)方法职责:为指定类加载器、一组接口及处理器生成动态代理类实例

  3)参数:

        loader:类加载器,一般传递真实对象的类加载器

        intrefaces:代理类需要实现的接口

        handler:代理对象如何做增强

 4)返回:创建的代理对象

 

2、java.lang.reflect.InvocationHandler接口   

public Object invoke(Object proxy,Method method,Object[] args)

方法职责:负责集中处理动态代理类上的所有方法调用

参数:

      proxy:生成的代理对象

      method:当前调用的真实方法对象

      args:当前调用方法的实参

返回:真实方法的返回结果

 

JDK动态代理操作步骤:

1.实现InvocationHandler接口,创建自己增强代码的处理器

2.给Proxy类提供ClassLoader对象和代理接口类型数组,创建动态代理对象

3.在处理器中实现增强操作

 

实现代码:

1.xml配置

<bean id="employeeDAO" class="com.bigfong.dao.impl.EmployeeDAOImpl" />

<bean id="transactionManager" class="com.bigfong.tx.TransactionManager" />

<bean id="employeeService" class="com.bigfong.service.impl.EmployeeServiceImpl">
	<property name="dao" ref="employeeDAO" />
</bean>

<!-- 配置一个事务增强的类 -->
<bean id="transactionManagerAdvice" class="com.bigfong.tx.TransactionManagerAdvice">
		<property name="target" ref="employeeService"/>
		<property name="txManager" ref="transactionManager"/>
</bean>

2.IEmployeeService接口类,EmployeeServiceImpl是对IEmployeeService的实现类

3.TransactionManager类

//模拟事务管理器:
public class TransactionManager {

	public void begin() {
		System.out.println("开启事务");
	}

	public void commit() {
		System.out.println("提交事务");
	}

	public void rollback() {
		System.out.println("回滚事务");
	}
}

4.TransactionManagerAdvice事务的增强类

@SuppressWarnings("all")
//事务的增强操作
public class TransactionManagerAdvice implements java.lang.reflect.InvocationHandler {

	private Object target;//真实对象(对谁做增强)
	private TransactionManager txManager;//事务管理器(模拟)

	public void setTxManager(TransactionManager txManager) {
		this.txManager = txManager;
	}

	public void setTarget(Object target) {
		this.target = target;
	}

	//创建一个代理对象
	public <T> T getProxyObject() {
		return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), //类加载器,一般跟上真实对象的类加载器
				target.getClass().getInterfaces(), //真实对象所实现的接口(JDK动态代理必须要求真实对象有接口)
				this);//如何做事务增强的对象
	}

	//如何为真实对象的方法做增强的具体操作
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
		Object ret = null;
		txManager.begin();
		try {
			//---------------------------------------------------------------
			ret = method.invoke(target, args);//调用真实对象的方法
			//---------------------------------------------------------------
			txManager.commit();
		} catch (Exception e) {
			e.printStackTrace();
			txManager.rollback();
		}
		return ret;
	}
}

5.调用

@Autowired
private TransactionManagerAdvice advice;


//代理对象:com.sun.proxy.$Proxy19
@Test
void testSave() throws Exception {
	//获取代理对象
	IEmployeeService proxy = advice.getProxyObject();
	proxy.save(new Employee());
}

@Test
void testUpdate() throws Exception {
	//获取代理对象
	IEmployeeService proxy = advice.getProxyObject();
	proxy.update(new Employee());
}

 

JDK代理总结:

1.java动态代理使用java.lang,reflect包中的Proxy类与InvocationHandler接口两个来完成

2.要使用JDK动态代理,委托必须要定义接口

3.JDK动态代理将会拦截所有public的方法(因为只能调用接口定义的方法),这样即使在接口中增加了新的方法,不用修改代码也会被拦截

4.动态代理的最小单位是类(类中的所有方法都会被处理),如果只想拦截一部分方法,可以在invoke方法中对要执行的方法名进行判断

 

上一篇:spring5整理:(四)其他重要注解

下一篇:spring5整理:(六)CGLIB动态代理-模拟事务 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值