java动态代理和AOP_笔记

先提一下反射的概念:

反射(Reflection):在程序编译的时候先不指定某个东西,然后在运行的时候再指定。反射被视为动态语言的关键。反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任何对象的内部属性及方法。

 

Java反射提供的功能:

1、 在运行时判断任意一个对象所属的类

2、 在运行时构造任意一个类的对象

3、 在运行时判断任意一个类所具有的成员变量和方法

4、 在运行时调用任意一个对象的成员变量和方法

5、 生成动态代理

为什么要动态代理?

在实际的开发中,总会存在相同的代码段重复出现的情况,在这种情况下,有种捷径就是选中那些相同的代码,然后通过“复制,粘贴”得的方式,完成软件开发。但是如果有一天需要对这些相同的代码完成修改的话,那就得在每一段包含这些相同代码的源代码进行修改,这需要耗费大量的时间。

下面是个实例图:

                        

最理想的效果就是:代码块1、代码2和代码3既可以执行深色代码部分,又无须在程序中以硬编码方式直接调用深色代码的方法,这时候就可以通过动态代理来达到这种效果。

下面是一个代码例子:

//定义一个接口
interface Human{
	void info();
	void fly();
}
//定义一个Human接口的实现类,为被代理类
class Superman implements Human
{

	@Override
	public void info() 
	{
		System.out.println("我是超人!");
	}

	@Override
	public void fly() 
	{
		System.out.println("我会飞!");
	}
	
}
//创建一个包含两个方法固定的类
class HumanUtil
{
	public void method01()
	{
		System.out.println("========方法一=======");
	}
	//想在这两个方法中间动态的插入一个方法
	public void method02()
	{
		System.out.println("========方法二=======");
	}
}
//动态代理
class TestInvocationHandler implements InvocationHandler{

	Object obj;//实现了接口的被代理类的对象的声明
	//通过这个方法传入一个Object obj对象
	//给被代理类的对象实例化;
	public void setObject(Object obj)
	{
		this.obj = obj;
		
	}
	@Override
	//返回一个代理类的对象
	public Object invoke(Object proxy, Method method, Object[] args) 
			throws Throwable 
	{
		HumanUtil h = new HumanUtil();
		//调用method01
		h.method01();
		//在method01和method02中间插入了一个方法,这个方法是动态的
		Object returnVal = method.invoke(obj,args);
		
		h.method02();
		
		return returnVal;
	}
	
}
//创建一个被代理类的对象,作用是动态地创建一个代理类对象
class MyProxy
{
	public static Object getProxyInstance(Object obj)
	{
		TestInvocationHandler handler = new TestInvocationHandler();
		handler.setObject(obj);
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);
	}
}

//测试类
public class TestAOP 
{

	public static void main(String[] args) 
	{
		//创建了一个被代理类的对象
       Superman man = new Superman();
       //返回man的代理对象
       Object obj = MyProxy.getProxyInstance(man);
       //因为代理类对象返回的man对象是实现了Human接口的,所以可以进行一个转型
		Human hu = (Human)obj;
		//通过代理类的对象调用重写的抽象方法
		hu.info();
		System.out.println();
		hu.fly();
	}

}


上面的代码例子中,HumanUtil方法一和方法二相当于相同的代码块。而当需要不同实现功能的代码块时,我们可以利用代理类对象动态的插入不同实现功能的代码块。


动态代理的实现步骤:

1、 首先包中存在被代理类

2、 创建一个代理类实现InvocationHandler接口,将被代理类传入该代理类中,创建一个set()实例化被代理类,并重写invoke()方法,返回一个被代理类对象。

3、 main方法中创建一个代理类对象,实例化代理类对象A,将A作为参数传入Proxy类的newProxyInstance()方法中。

4、 返回的Proxy对象进行强制转换,得到的那个对象就可以当成被代理类了。


下面是AOP代理的方法与目标对象的方法示意图

                    

而面向切面编程相当于在HumanUtil固定的方法一和方法二当中插入我们想要的其他功能的代码。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值