java AOP使用及jdk动态代理原理

简介

AOP(面向切面编程)可以说是OOP的补充和完善。它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个一个可重用模块,并将其命名为“Aspect”,及切面。所谓切面,简单说就是那些与业务无关,缺位业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性性和可维护性。

AOP动态代理代码:

public class AnimalFactory {

	/***
	 * 获取对象方法
	 * @param obj
	 * @return
	 */
	private static Object getAnimalBase(Object obj,AOPMethod method){
		//获取代理对象
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), 
				obj.getClass().getInterfaces(), 
				new AOPHandle(AnnoInjection.getBean(obj),method));
	}
}

其中AOPHandle类的定义如下:

public class AOPHandle implements InvocationHandler{
	//保存对象
	private AOPMethod method;
	private Object o;
	public AOPHandle(Object o,AOPMethod method) {
		this.o=o;
		this.method=method;
	}
	/**
	 * 这个方法会自动调用,Java动态代理机制
	 * 会传入下面是个参数
	 * @param Object proxy	代理对象的接口,不同于对象
	 * @param Method method	被调用方法
	 * @param Object[] args	方法参数
	 * 不能使用invoke时使用proxy作为反射参数时,因为代理对象的接口,不同于对象
	 * 这种代理机制是面向接口,而不是面向类的
	 **/
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object ret=null;
		//修改的地方在这里哦
		this.method.before(proxy, method, args);
		ret=method.invoke(o, args);
		//修改的地方在这里哦
		this.method.after(proxy, method, args);
		return ret;
	}
}

补充说明:

java.lang.reflect.Proxy中newProxyInstance函数定义如下:
    @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) {
        Objects.requireNonNull(h);
        Class<?> caller = System.getSecurityManager() == null ? null : Reflection.getCallerClass();
        Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);
        return newProxyInstance(caller, cons, h);
    }

AOP代理调用验证代码:

public class AOPTest {

	public static void main(String[] args) {

		AnimalInterface dog = AnimalFactory.getAnimal(DogImp.class, new AOPMethod() {
			// 这里写方法执行前的AOP切入方法
			public void before(Object proxy, Method method, Object[] args) {
				if (method.getName().equals("getProperty")) {
					System.err.println("成功拦截" + method.getName() + "方法,启动");
				}
			}

			// 这里系方法执行后的AOP切入方法
			public void after(Object proxy, Method method, Object[] args) {
				if (method.getName().equals("getProperty"))
					System.err.println("成功拦截" + method.getName() + "方法,结束");

			}
		});
		dog.say();
		String name1 = "我的名字是" + dog.getName();
		System.out.println(name1);
		dog.setName("二狗子");
		String name2 = "我的名字是" + dog.getName();
		System.out.println(name2);
		dog.getProperty();
	}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值