SpringAOP功能学习笔记(一)

一.spring容器有两大核心功能IOC(控制反转)和AOP(面向切面编程).

IOC:为我们创建和管理对象,还可以维护对象之间的关系,不仅使代码简洁易懂,而且耦合度大大降低.

AOP:使核心业务和其他业务分离,不仅减少了代码量,而且有利于协作开发

二.SpringAOP功能是如何实现的?

    是基于动态代理实现的.

三.什么是动态代理,什么是静态代理?

    1.代理的基本构成:

        抽象角色:声明真实对象和代理对象的共同接口(interface).

        代理角色:代理对象内部含有真实对象的引用,从而在任何时候都可以操作真实对象.(其他业务问题+核心问题)

        真实角色:是我们最终要引用的对象(解决核心问题)

    2.静态代理

        2.1创建抽象角色

public interface Subject {//抽象角色
	public void doSomething();
}

        2.2创建真实角色

public class RealSubject implements Subject {//真实角色

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

        2.3创建代理角色

public class SubjectProxy implements Subject {//代理角色
	//包含真实对象的引用,能够操作真实对象
	Subject subImpl = new RealSubject();
	
	@Override
	public void doSomething() {
		System.out.println("before");//调用目标对象之前可以执行操作
		subImpl.doSomething();
		System.out.println("after");//调用目标对象之后可以执行操作
	}

}

        2.4创建测试类测试

public class Test {
	public static void main(String[] args) {
		Subject subject = new SubjectProxy();
		subject.doSomething();
	}
}

        结果为:

    

    3.静态代理的缺点

        3.1.当真实角色实现了新的接口后,代理类需要和真实角色一样实现此接口,也需要添加此接口的引用,代理类会变得 臃肿

        3.2.当真实角色改变接口时,代理类需要改变接口引用

        总之:静态代理中真实角色和代理角色有强耦合关系,不利于代码的拓展和维护

    4.JDK动态代理

    基于java反射机制解决静态代理的缺点

        4.1创建抽象角色(同静态代理)

        4.2创建真实角色(同静态代理)

        4.3创建代理角色

package proxyHandlerTest01;

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

public class ProxyHandler implements InvocationHandler {
	
	private Object tar;
	
	/**
	 * 绑定委托对象,获取代理类
	 * @param tar 目标对象
	 * @return	代理类
	 */
	public Object bind(Object tar){
		this.tar = tar;
		//绑定该类实现的所有接口,取得代理类
		return Proxy.newProxyInstance(tar.getClass().getClassLoader(),
				tar.getClass().getInterfaces(), this);
	}
	
	/**
	 * 此方法不会显式地调用
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object result = null;
		System.out.println("before");
		result = method.invoke(tar, args);
		System.out.println("after");
		return result;
	}

}

        4.4测试代理类

package proxyHandlerTest01;

import java.lang.reflect.Proxy;

public class Test {
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, Throwable {
		ProxyHandler proxy = new ProxyHandler();
		Subject subject = (Subject)proxy.bind(new RealSubject());
		subject.doSomething();
		
		System.out.println("\n代理类是否继承Proxy类:"+(subject instanceof Proxy));
		System.out.print("代理类实现的接口为:");
		Class<?>[] cls = subject.getClass().getInterfaces();
		for(Class<?> c:cls){
			System.out.println(c);
		}
		System.out.println("代理类名称为:"+subject.getClass().toString());
		
	}
}

        测试结果为:

        

        总结: 1.JDK动态代理利用java反射机制简单粗暴的为目标对象创建代理对象

                2.JDK动态代理解决了静态代理的缺点,不论目标类怎么变化,代理类不需要改变!

                3.该对象继承Proxy类,实现目标对象的所有接口

                4.JDK动态代理核心为:Proxy类和invocationHandler回调接口(面试常问)

    注意:JDK动态代理只适用于目标类实现了接口!!

四.除了JDK动态代理,SpringAOP还有cglib动态代理

    cglib动态代理解决了JDK动态代理的缺点,它可以为不实现接口的目标对象动态创建代理类

    区别于JDK动态代理底层原理基于java反射,cglib动态代理的底层是通过一个字节码处理框架asm,来转换字节码并生成新的类.

    cglib核心:

    MethodInterceptor:实现此接口可以定义方法的拦截器,即定义拓展功能

    Enhancer:生成代理类的字节码

    注意:    1.生成的代理类继承了目标类,所以调用目标类的方法时,会执行代理类的方法

                2.由于目标类需要被代理类继承,所以目标类如果带有final修饰词,则无法使用cglib生成代理类!


        

    

    


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值