Spring AOP 代理模式

AOP理解:就是把 业务代码和关注点代码分离开来,关注点就是(重复的代码、方法)
切面就是 关注点形成的类

例如,当用户直接访问目标对象进行数据库操作,当发生错误返回一场。这样显然是不合理的,这时候中间就需要代理对象。
就好比商家 需要商演,你想找某个明星出演活动,你不可能直接去找明星谈合作,你可以通过经纪人来谈合作;
第一种静态代理

package com.staticpackage;

public interface IUserDao {

public void save() throws Exception;
}


package com.staticpackage;
/**
 * 目标对象
 * @author 11947
 *
 */
public class UserDao implements IUserDao{

	@Override
	public void save() {
		
		System.out.println("数据已经保存");
	}

}

静态代理

package com.staticpackage;
/**
 * 代理对象(静态代理)
 * @author 11947
 *
 */
public class UserDaoProxy implements IUserDao {
private IUserDao target;
public UserDaoProxy(IUserDao target) {
	this.target=target;
	
}
@Override
public void save() throws Exception {
	// TODO Auto-generated method stub
	System.out.println("开启事务");
	target.save();
	System.out.println("提交事务");
}

}

测试类

package com.staticpackage;

public class Test {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		IUserDao target = new UserDao();
		UserDaoProxy proxy = new UserDaoProxy(target);
		proxy.save();
	}

}

静态代理的缺点:因为代理对象需要实现与目标对象相同的接口,会有很多代理,类接口增加方法,目标对象与代理对象都需要维护。为了解决这一点,就需要jdk动态代理

第二种动态代理(jdk代理)

package com.dynamic;

public interface IUserDao {

public void save() throws Exception;
}

package com.dynamic;
/**
 * 目标对象
 * @author 11947
 *
 */
public class UserDao implements IUserDao{

	@Override
	public void save() {
		
		System.out.println("数据已经保存");
	}

}

package com.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyFactory {
 //目标对象
	private Object target;
	
	public ProxyFactory(Object target) {
		this.target= target;
		
	}
	//生成代理对象 
	public Object getProxyInstance() {
		return Proxy.newProxyInstance(//jdk中的方法目标对象必须有实现接口,否则不能使用动态代理
				target.getClass().getClassLoader(),//获取目标对象类加载器
				target.getClass().getInterfaces(),//目标对象实现的接口类型
				new InvocationHandler() {         //事件处理器
					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						// TODO Auto-generated method stub
						System.out.println("开启事务");
						Object result=method.invoke(target, args);
						System.out.println("提交事务");
						return result;
					}
				});
		
		
		
	}
}

package com.dynamic;
/**
 * 
 * 目标
 * 
 * @author 11947
 *
 */
public class Test {

	public static void main(String[] args) throws Exception {
	IUserDao target=new UserDao();
	IUserDao proxy=(IUserDao) new ProxyFactory(target).getProxyInstance();
	
	proxy.save();
	}

}

第三种cglib代理

package com.cglib;
/**
 * 目标对象
 * @author 11947
 *
 */
public class UserDao{

	
	public void save() {
		
		System.out.println("数据已经保存");
	}

}

package com.cglib;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

/**
 * cglib子类工厂(对UserDao在内存中动态创建一个代理)
 * @author 11947
 *
 */
public class ProxyFactory implements MethodInterceptor {
//目标对象 
private Object target;
public ProxyFactory(Object target) {
	this.target=target;
}
public Object getProxyInstance() {
	//1.工具类
			Enhancer en=new Enhancer();
			//2.设置父类
			en.setSuperclass(target.getClass());
			//3.设置回调函数
			en.setCallback(this);
			//4.创建代理对象
			return en.create();
	
}	
	@Override
	public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable {
		//执行目标对象的方法
		System.out.println("开启事务");
		Object resultValue=method.invoke(target, arg2);
		System.out.println("提交事务");
		return resultValue;
		
	}

}

package com.cglib;
/**
 * 
 * cglib代理  子类代理,在内存中构建一个子类对象从未实现对目标对象的扩展
 * 
 * 在内存中动态创建对象的子类
 * 目标对象不可以是final
 * 目标对象方法是final、staic,则不会拦截
 * 
 * 
 * @author 11947
 *
 */
public class Test {

	public static void main(String[] args) throws Exception {
	  //目标对象
		UserDao target=new UserDao();
      //代理对象
		UserDao proxy=(UserDao) new ProxyFactory(target).getProxyInstance();
	    proxy.save();
	    System.out.println(proxy.getClass());
	}

}

cglib代理不需要有接口,它是在内存中创建一个子类对象,从而对目标对象的扩展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值