java动态代理

最近在研究spring事务管理器的一些东西

偶然在知乎上看到一篇文章

链接如下 https://www.zhihu.com/question/36948563

其中有一段话:

Spring事务处理逻辑是以切面的方式织入到业务(代理)对象中的。如果一个业务对象中两个方法(a,b)都配置了事务逻辑,如果在业务对象中方法a中直接调用了方法b,则这只是简单的方法级别调用,方法b上面的事务根本就在本次调用中感知不到。所以场景1,在调用了业务(代理)对象的a方法,a方法在调用b方法时抛出了异常,而且你在a方法体内catch了这个异常,对于调用者来说,a方法调用是正常的。场景2,你调用了业务(代理)对象的b方法,但是在调用处catch了异常,代理对象b方法的异常已经抛给了事务切面,事务已经回滚啦。如果你想在a方法中保证b方法的事务性,则在方法a中必须要获得业务(代理)对象,你可以在配置中添加
  1. <!-- 开启暴露Aop代理到ThreadLocal支持  -->  
  2.     <aop:aspectj-autoproxy expose-proxy="true"/>  
  3. 在使用该标签时 需要在aop:config标签中添加 proxy-target-class="true"  否则会类型转换错误
  4. 具体看http://www.cnblogs.com/xing901022/p/4264172.html

然后通过Service service = (Service) AopContext.currentProxy();获取代理类 调用代理类的方法 

Java动态代理主要涉及到两个类:

  • InvocationHandler:该接口中仅定义了一个Object : invoke(Object proxy, Method method, Object[] args);参数proxy指代理类,method表示被代理的方法,args为method中的参数数组,返回值Object为代理实例的方法调用返回的值。这个抽象方法在代理类中动态实现。
  • Proxy:所有动态代理类的父类,提供用于创建动态代理类和实例的静态方法。

所谓动态代理类是在运行时生成的class,在生成它时,你必须提供一组interface给它,则动态代理类就宣称它实现了这些interface。当然,动态代理类就充当一个代理,你不要企图它会帮你干实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。

于是我用写了个小程序验证了下是否真的如此:
代码如下:
UserService.java
public interface UserService
{

	public void add();
	public void select();
	
}


UserServiceImpl.java

public class UserServiceImpl implements UserService
{

	public UserServiceImpl()
	{
		// TODO Auto-generated constructor stub
	}

	@Override
	public void add()
	{
		System.out.println("add");
		
	}
	
	public void delete()
	{
		
		System.out.println("delete");
		
	}

	@Override
	public void select()
	{
		add();
		System.out.println("select");
	}

}



JDK动态代理代理类 

实现invocationHandler接口

//obj为实际需要去代理的类 在这里是UserServiceImpl类的实例

ServiceProxy.java

public class ServiceProxy implements InvocationHandler
{

	private Object obj;

	public ServiceProxy(Object obj){
		this.obj = obj;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
	{
		System.out.println("事物开始");  
        //执行方法  
		
        Object result=method.invoke(obj, args);  
        System.out.println("事物结束");  
        return result;  
	}


}


测试类ProxyTest.java

public class ProxyTest
{

	public ProxyTest()
	{
		// TODO Auto-generated constructor stub
	}
	
	
	public static void main(String[] args){
		UserServiceImpl u = new UserServiceImpl();
		ServiceProxy proxy = new ServiceProxy(u);
		UserService service = (UserService) Proxy.newProxyInstance(proxy.getClass().getClassLoader(),u.getClass().getInterfaces() , proxy);
		service.add();
		System.out.println("-------------");
		service.select();
		
		
	}

}

实际输出如下:

事物开始
add
事物结束
-------------
事物开始
add
select
事物结束


select方法中的add方法并没有执行代理方法 可见  那段话的确是正确的



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值