1.声明一个接口
package com.fh.service.aop;
public interface AopManager { int add();
void list(); String delete(); void update(); void transfer();}
2.实现一个接口的被代理类
package com.fh.service.aop.impl;
import org.springframework.stereotype.Service;
import com.fh.service.aop.AopManager;
@Service(“aopService”) public class AopService implements AopManager{
@Override public int add() { // TODO Auto-generated method stub System.out.println("AOPadd.........."); return 100; } @Override public void list() { // TODO Auto-generated method stub System.out.println("AOPlist.........."); } @Override public String delete() { // TODO Auto-generated method stub System.out.println("AOPdelete....."); return "delete ex"; } @Override public void update() { // TODO Auto-generated method stub System.out.println("update........."); int i=1/0; } @Override public void transfer() { // TODO Auto-generated method stub System.out.println("实现接口的动态代理增强类"); }}
3.未实现接口的被代理类 package com.fh.service.aop.impl;
public class proxyService{
public void proxy() { // TODO Auto-generated method stub System.out.println("没有实现接口动态代理增强类"); }}
4.使用JDK动态代理一个实现接口的被代理类 package com.fh.util.aop;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.fh.service.aop.AopManager; import com.fh.service.aop.impl.AopService;
/**JDK动态代理增强类
@author Administrator*/ public class JDKAdvice implements InvocationHandler { //目标对象 private AopManager target;
public JDKAdvice() { } public JDKAdvice(AopManager target) { this.target = target; } /** * 代理方法, 每次调用目标对象方法时都会进到这里 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); return method.invoke(target, args); } /** * 前置增强方法 */ private void before() { System.out.println("JDK动态代理前置增强通知"); } public static void main(String[] args) { //创建目标对象 AopManager target = new AopService(); //创建代理对象 AopManager proxy = (AopManager) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new JDKAdvice(target) ); //调用目标对象方法 proxy.transfer(); }}
输出以下内容: JDK动态代理前置增强通知 实现接口的动态代理增强类
5.使用JDK动态代理一个没有实现接口的被代理类(执行发生异常) package com.fh.util.aop;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;
import com.fh.service.aop.impl.proxyService;
public class ErrorJDKProxy implements InvocationHandler{
//目标对象 private proxyService target; public ErrorJDKProxy(proxyService target) { this.target = target; } /** * 代理方法, 每次调用目标方法时都会进到这里 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); return method.invoke(target, args); } /** * 前置增强 */ private void before() { System.out.println("JDK动态代理前置增强通知"); } public static void main(String[] args) { //创建目标对象 proxyService target = new proxyService(); //创建代理对象 proxyService proxy = (proxyService) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new ErrorJDKProxy(target) ); proxy.proxy(); }}
输出以下内容: Exception in thread “main” java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to com.fh.service.aop.impl.proxyService at com.fh.util.aop.ErrorJDKProxy.main(ErrorJDKProxy.java:39)
6.使用CGLIB动态代理一个没有实现接口的被代理类 package com.fh.util.aop;
import java.lang.reflect.Method;
import com.fh.service.aop.impl.proxyService;
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;
public class CGLIBAdvice implements MethodInterceptor { /** * 代理方法, 每次调用目标方法时都会进到这里 */ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { before(); return methodProxy.invokeSuper(obj, args); // return method.invoke(obj, args); 这种也行 }
/** * 前置增强 */ private void before() { System.out.println("CGLIB动态代理前置增强通知"); } public static void main(String[] args) { //创建目标对象 proxyService target = new proxyService(); //创建代理对象 proxyService proxy = (proxyService) Enhancer.create(target.getClass(), new CGLIBAdvice()); proxy.proxy(); }}
输出以下内容: CGLIB动态代理前置增强通知 没有实现接口动态代理增强类
JDK 和 CGLib动态代理性能对比 (1)CGLib所创建的动态代理对象在实际运行时候的性能要比JDK动态代理高不少,有研究表明,大概要高10倍。 (2)但是CGLib在创建对象的时候所花费的时间却比JDK动态代理要多很多,有研究表明,大概有8倍的差距。 (3)因此,对于singleton的代理对象或者具有实例池的代理,因为无需频繁的创建代理对象,所以比较适合采用CGLib动态代理,反正,则比较适用JDK动态代理。