模拟spring,Aop(JDK与CGLib两种方式实现)

一、AOP以JDK版实现

1.定义接口

package cn.hq.service;

public interface StudentService {
	public String getUser() throws Exception;
	public void save(String name) throws Exception;
	public void update(String name) throws Exception;
}


2.接口实现

package cn.hq.service.impl;

import cn.hq.service.StudentService;

public class StudentServiceImpl implements StudentService {
	
	private String user;
	public String getUser() {
		return user;
	}
	
	public StudentServiceImpl() {}
	
	public StudentServiceImpl(String user) {
		this.user = user;
	}
	
	public void save(String name) throws Exception {
		System.out.println("save()==>" + name);
	}
	
	public void update(String name) {
		System.err.println("update()==>" + name);
	}


}


3.代理类工厂

package cn.hq.aop;

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

import cn.hq.service.StudentService;


public class JDKProxyFactory implements InvocationHandler{
	private Object targetObject;
	public JDKProxyFactory() {}
	
	
	public Object createProxyInstance(Object targetObject) {
		this.targetObject = targetObject;
		return Proxy.newProxyInstance(
				this.targetObject.getClass().getClassLoader(),  //类加载器
				this.targetObject.getClass().getInterfaces(), 	//类中的所有接口
				this); //当前对象   此处较为重要  通过此处回调 invoke函数 
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) 
			throws Throwable { //--环绕通知
		
		StudentService bean = (StudentService)this.targetObject;
		Object result = null;
		if(bean.getUser() != null) {
			//---spring中的advice()---前置通知
			try {
				result = method.invoke(targetObject, args);
				//afterAdivice()-----后置通知
			} catch (Exception e) {
				// exceptionAdivce()---异常通知
			}finally {
				//finallyAdive()----后置通知
			}
			
			
			
		}
		
		return result;
	}
}


4.测试

	@Test
	public void proxyTest() {
		JDKProxyFactory factory =new JDKProxyFactory();
		StudentService studentService = (StudentService) factory.createProxyInstance(new StudentServiceImpl("zzz"));
		try {
			
			if(studentService.getUser() != null && !"".equals(studentService.getUser())) {
				studentService.save("dddd");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			
		}
	}


二、AOP以CGLib实现

1.定义方法类

package cn.hq.service.impl;

public class TeacherServiceBean {
	
	private String user;
	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}
	
	public void save() throws Exception{
		System.out.println(this.getClass().getName() + "====>save()");
	}
}


2.代理类工厂

package cn.hq.aop;

import java.lang.reflect.Method;

import cn.hq.service.impl.TeacherServiceBean;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGlibProxyFactory implements MethodInterceptor{

	private Object targetObject;
	public Object createProxyInstance(Object targetObject) {
		this.targetObject = targetObject;
		
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.targetObject.getClass()); //非Final
		enhancer.setCallback(this);
		return enhancer.create();
	}
	
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) 
			throws Throwable { //--环绕通知
		TeacherServiceBean teacherServiceBean = (TeacherServiceBean)this.targetObject;
		Object result = null;
		if(teacherServiceBean.getUser() != null) {
			//---spring中的advice()---前置通知
			try {
				result = methodProxy.invoke(targetObject, args);
				//afterAdivice()-----后置通知
			} catch (Exception e) {
				// exceptionAdivce()---异常通知
			}finally {
				//finallyAdive()----后置通知
			}
			
		}
		
		return result;
	}
}


3.测试

	@Test
	public void cglibProxyTest() {
		CGlibProxyFactory factory =new CGlibProxyFactory();
		TeacherServiceBean bean = (TeacherServiceBean) factory.createProxyInstance(new TeacherServiceBean());
		try {
			bean.save();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			
		}
	}

4.注,CGLib实现需要添加jar包

asm-3.3.1.jar

cglib-2.2.2.jar


三、两者的区别

JDK版的代理实现,方法类必须要有接口实现。。采用的动态代理的方式

CGLib不需要实现接口。。具体是使用继承的重载的方式


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值