Spring--- AOP的认识

AOP(面向切面编程):

AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)。传统的使用继承来增强代码达到代码复用的效果(继承写入日志功能),而Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码。

AOP底层原理:代理机制(动态代理,对实现了接口的类生成代理)

Spring AOP:JDK动态代理,实现了接口的类生成代理CGLib代理机制:对类生成代理

AOP的几个关键术语:

Joinpoint:连接点,可以被拦截(增强)的方法。

Pointcut:切入点,对哪些连接点 进行拦截(增强)。

Advice: 通知,用于增强的 代码(记录日志的代码)针对于方法的增强。

introduction:引介, 特殊方式的Advice, (类级别的增强)

Target:目标对象, 被增强的对象, 代理的目标对象

weaving:织入,把增强应用到目标对象创建新的代理对象的过程。

两种动态代理:(1)JDK动态代理 (2)CGLib代理机制

JDk动态代理机制:

示例:

public interface UserDao {
	public void add();
	public void delete();
}

public class userDaoimpls implements UserDao{

	public void add() {
		// TODO Auto-generated method stub
		System.out.println("添加了。。。。");
	}

	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("删除了。。。。");
	}

}

public class JDKProxy implements InvocationHandler{
    private UserDao userdao;
    //使用构造方法传入目标对象
    public JDKProxy(UserDao userdao) {
        super();
        this.userdao = userdao;
    }
    //创建代理对象
    public UserDao createProxy(){
        //参数:1. 指定被代理对象的类加载器,2. 指定被代理对象所实现的接口 3.指定需要调用的InvocationHandler对象(通过类来实现InvocationHandler的接口)
        UserDao proxy = (UserDao) Proxy.newProxyInstance(userdao.getClass().getClassLoader(), userdao.getClass().getInterfaces(), this);
        return proxy;
        
    }
    //通过代理调用目标对象的方法。相当于调用invoke()
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // TODO Auto-generated method stub
        if(method.getName()=="add"){
            //增强代码,记录日志
            System.out.println("日志:开始添加");
            Object o = method.invoke(userdao, args);
            return o;
        }
        return method.invoke(userdao, args);
    }
}

测试类:

public class ProxyTest {
    @Test
    public void text1(){
        UserDao userdao = new userDaoimpls();
        UserDao proxy = new JDKProxy(userdao).createProxy();
        proxy.add();
        proxy.delete();
    }
}

测试结果;在添加用户之前 显示日志信息,通过动态代理的方式实现了方法的增强。

(2)CGLib代理机制

CGLIB(Code Generation Library)是一个开源项目!是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。 Hibernate支持它来实现PO(Persistent Object 持久化对象)字节码的动态生成

示例:

public class ProductDao {
	public void add(){
		System.out.println("添加商品哦");
	}
	public void delete(){
		System.out.println("删除商品哦");
	}
}
<pre name="code" class="java">public class CGLIBProxy implements MethodInterceptor{
	private ProductDao productdao;
	//传入目标对象
	public CGLIBProxy(ProductDao productdao) {
		super();
		this.productdao = productdao;
	}
	//生成代理对象
	public ProductDao createProxy(){
		//使用cgLib
		//1. 创建核心类
		Enhancer enhancer = new Enhancer();
		//设置父类,使生成的代理对象为目标对象的子类
		enhancer.setSuperclass(productdao.getClass());
		//3. 设置回调(通过类实现MethodInterceptor接口,生成calback对象)
		enhancer.setCallback(this);
		//4. 创建代理
		return (ProductDao) enhancer.create();
	}
	
	//这个方法与JDK动态代理的invoke方法类似。
	@Override
	public Object intercept(Object proxy, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		// TODO Auto-generated method stub
		if("add".equals(method.getName())){
			System.out.println("日志开始记录");
			//proxy时productdao的子类,父类的方法它都拥有
			Object b1 = methodProxy.invokeSuper(proxy, args);
			return b1;
		}
		return methodProxy.invokeSuper(proxy, args);
	}
	
}

public class Proxytest {
    @Test
    public void test1(){
        ProductDao productdao = new ProductDao();
        ProductDao proxy = new CGLIBProxy(productdao).createProxy();
        proxy.add();
        proxy.delete();
    }
}

 由此可以得出:当使用Spring框架时,对于实现了接口的类,使用JDK动态代理,对于没有实现任何接口的类,使用CGLIB动态代理。 







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值