1.为什么要使用代理
2.静态代理
2.1概念
2.2代码实现
1.定义业务接口
package com.bj.service; //本代理的接口将要被增强 public interface ISomeService { String doFirst(); void doSecond(); }
2.定义目标类,该类实现了业务接口
package com.bj.service; //代理类将要增强的类 public class SomeServiceImpl implements ISomeService { @Override public String doFirst() { System.out.println("执行doFirst方法"); return "abcd"; } @Override public void doSecond() { System.out.println("执行doSecond方法"); } }
3.定义代理类
这个类要实现ISomeService接口,并且该代理类要讲接口对象作为一个成员变量,还要定义一个带餐的构造器,这个参数为接口对象。目的是将目标对象引入代理类,以便代理类调用目标类的方法。
package com.bj.proxy; import com.bj.service.ISomeService; public class ServiceProxy implements ISomeService { private ISomeService target; public ServiceProxy() { // Source快捷键:alt+shift+s + c } public ServiceProxy(ISomeService target) { this.target = target; } @Override public String doFirst() { String result = target.doFirst(); // 增强:将目标方法返回的全小写字母,转化为全大写 return result.toUpperCase(); } @Override public void doSecond() { target.doSecond(); } }
4.测试
package com.bj.test; import com.bj.proxy.ServiceProxy; import com.bj.service.ISomeService; import com.bj.service.SomeServiceImpl; public class MyTest { public static void main(String[] args) { ISomeService target = new SomeServiceImpl(); ISomeService service = new ServiceProxy(target); // rename:alt+shift+r String result = service.doFirst(); System.out.println(result); service.doSecond(); } }
3.JDK动态代理
3.1概念
3.2代码
1.定义业务接口ISomeService
package com.bj.service; //本代理的接口将要被增强 public interface ISomeService { String doFirst(); void doSecond(); }
2.定义目标类ISomeServiceImpl
package com.bj.service; //代理类将要增强的类 public class SomeServiceImpl implements ISomeService { @Override public String doFirst() { System.out.println("执行doFirst方法"); return "abcd"; } @Override public void doSecond() { System.out.println("执行doSecond方法"); } }
以上两个步骤与静态代理类中代码相同。
3.测试类
package com.bj.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.bj.service.ISomeService; import com.bj.service.SomeServiceImpl; public class MyTest { public static void main(String[] args) { ISomeService target = new SomeServiceImpl(); // 由proxy类的newProxyInstance方法生成的一个动态代理对象 ISomeService service = (ISomeService) Proxy.newProxyInstance(target.getClass().getClassLoader(), // 目标类的类加载器 target.getClass().getInterfaces(), // 目标类所实现的所有接口 new InvocationHandler() { // 目标类的匿名内部类 // proxy:代理对象 // method:目标方法 // args:目标方法的参数列表 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(target, args); if (result!=null) { //添加if的快捷键:alt+shift+z,3 result = ((String) result).toUpperCase(); //抽取一个变量的快捷键 ctrl+shift+l } return result; } }); // rename:alt+shift+r String result = service.doFirst(); System.out.println(result); service.doSecond(); } }
4.CGLIB动态代理
4.1概念
4.2代码实现
1.导入jar包
2.定义目标类,注意不用实现任何接口
package com.bj.service; //目标类:没有实现任何接口 public class SomeService { public String doFirst() { System.out.println("执行doFirst方法"); return "abcd"; } public void doSecond() { System.out.println("执行doSecond方法"); } }
3.创建代理类的工厂。该类要实现MethodIntercept接口
package com.bj.factory; import java.lang.reflect.Method; import com.bj.service.SomeService; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; //注意:使用cglib动态代理,要求目标类不能是final的 //因为final类是不能有子类的,而cglib动态代理增强的原理是:子类增强父类 public class CglibFactory implements MethodInterceptor { private SomeService target; //1.声明目标类的成员变量,并创建以目标类为参数的构造器,用于接收目标对象 public CglibFactory() { } public CglibFactory(SomeService target) { this.target = target; } public SomeService myCglibCreator() { //2.定义代理类的生成方法,用于创建代理对象 Enhancer enhancer = new Enhancer(); //指定父类,即目标类。因为cglib动态代理增强的原理是:子类增强父类 enhancer.setSuperclass(SomeService.class); //设置回调接口对象 enhancer.setCallback(this); //create()方法用于创建cglib动态代理对象方法,即目标类的子类对象 return (SomeService) enhancer.create(); } //回调接口的方法 @Override //3.定义回调接口方法。对目标类的增强在这里完成 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object invoke = method.invoke(target, args); if (invoke!=null) {//添加if的快捷键:alt+shift+z,3 invoke = ((String) invoke).toUpperCase(); } return invoke; } }
4.测试
package com.bj.test; import com.bj.factory.CglibFactory; import com.bj.service.SomeService; public class MyTest { public static void main(String[] args) { SomeService target = new SomeService(); SomeService service = new CglibFactory(target).myCglibCreator(); String result = service.doFirst(); System.out.println(result); service.doSecond(); } }