1.静态代理
package study.proxy.ststic;
/**
* 接口
* 一个人可以被代理的行为
* @author an
*
*/
public interface PersonAction {
public void buyHouse();
public void findJob();
}
package study.proxy.ststic;
/**
* 工人
* @author an
*
*/
public class Worker implements PersonAction {
@Override
public void buyHouse() {
System.out.println("工人:我要买一套两居室的价格在30万左右的房子");
}
@Override
public void findJob() {
System.out.println("工人:我想找一个不拖欠工资的工作");
}
}
package study.proxy.ststic;
/**
* 白领
* @author an
*
*/
public class WhiteCollar implements PersonAction {
@Override
public void buyHouse() {
System.out.println("白领:我想买一套交通方便的房子,面积不要太大");
}
@Override
public void findJob() {
System.out.println("白领:我想找一份加班少待遇好的公司");
}
}
package study.proxy.ststic;
/**
* 我们是代理各种需求的中介
* @author an
*
*/
public class Agency implements PersonAction {
private PersonAction person;
public Agency(PersonAction person){
this.person=person;
}
@Override
public void buyHouse() {
System.out.println("中介:您好,欢迎选择购房中介,您有什么需求?");
person.buyHouse();
System.out.println("中介:我的我们尽快帮您找到合适的房源");
}
@Override
public void findJob() {
System.out.println("中介:您好,欢迎光临工作无忧,您对工作有什么需求?");
person.findJob();
System.out.println("中介:感谢您的光临,我们尽快帮你 匹配合适的岗位。");
}
}
package study.proxy.ststic;
public class AgencyTest {
public static void main(String[] args) {
Worker worker = new Worker();
WhiteCollar wc = new WhiteCollar();
Agency agency1 = new Agency(worker);
agency1.buyHouse();
agency1.findJob();
System.out.println();
Agency agency2 = new Agency(wc);
agency2.buyHouse();
agency2.findJob();
}
}
2.JDK动态代理
package study.proxy.JDK;
/**
* 目标类要实现的接口
* @author an
*
*/
public interface JDKDemoInter {
public void detailShow(String s);
}
package study.proxy.JDK;
/**
* 要被代理的类
* 必须要有实现的接口
* @author an
*
*/
public class JDKClassDemo implements JDKDemoInter{
private String name;
public void detailShow(String s){
System.out.println("你好我是JDKClassDemo,你输入的是"+s);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package study.proxy.JDK;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* jdk动态代理
* 使用java.lang.reflect.Proxy类来实现代理
* @author an
*
*/
public class JDKProxy1 {
//被代理的目标对象
private Object obj;
public JDKProxy1(Object obj){
this.obj = obj;
}
//生成代理对象
/**
* ClassLoader 对象的类加载器
* Class<?>[] interfaces 目标对象实现的接口类型
* InvocationHandler 事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入
* @return
*/
public Object getProxyInstance(){
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
System.out.println("执行前");
Object returnObj = method.invoke(obj, args);
System.out.println("执行后");
return returnObj;
}});
}
}
package study.proxy.JDK;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* JDK动态代理的实现2
* @author an
*
*/
public class JDKProxy2 implements InvocationHandler{
private Object obj;
public Object getInstance(Object objc){
this.obj=objc;
return Proxy.newProxyInstance(objc.getClass().getClassLoader(), objc.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("执行前");
//第一个参数必须传obj
Object returnObj = method.invoke(this.obj, args);
System.out.println("执行后");
return returnObj;
}
}
package study.proxy.JDK;
public class JDKProxyTest {
public static void main(String[] args) {
JDKClassDemo demo = new JDKClassDemo();
JDKDemoInter proxyDemo = (JDKDemoInter)new JDKProxy1(demo).getProxyInstance();
proxyDemo.detailShow("000");
JDKClassDemo demo1 = new JDKClassDemo();
JDKDemoInter proxyDemo1 = (JDKDemoInter)new JDKProxy2().getInstance(demo1);
proxyDemo1.detailShow("111");
}
}
3.cglib动态代理
package study.proxy.Cglib;
/**
* 被代理的目标类
* 不需要实现接口
* 代理的类不能为final,否则报错
* 目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法
* @author an
*
*/
public class CglibClass {
public void say(){
System.out.println("this is CglibClass");
}
public static void say1(){
System.out.println("this is static");
}
public final void say2(){
System.out.println("this is final");
}
}
package study.proxy.Cglib;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
/**
* cglib代理类
* Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的被许多AOP的框架使用,
* 例如Spring AOP和synaop,为他们提供方法的interception(拦截)
*
* Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类
*
* Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展.
* @author an
*
*/
public class CglibProxy implements MethodInterceptor{
//目标对象
private Object obj;
public CglibProxy(Object obj){
this.obj=obj;
}
//生成代理对象
public Object getProxyInstance(){
//设置工具类
Enhancer en = new Enhancer();
//设置父类
en.setSuperclass(obj.getClass());
//设置回调函数
en.setCallback(this);
//返回创建的子类(代理对象),因为cglib又被称为子类代理
return en.create();
}
@Override
public Object intercept(Object arg0, Method method, Object[] arg2,
MethodProxy arg3) throws Throwable {
System.out.println("执行前");
Object returnObj = method.invoke(obj, arg2);
System.out.println("执行后");
return returnObj;
}
}
package study.proxy.Cglib;
public class CglibTest {
public static void main(String[] args) {
CglibClass cglib = new CglibClass();
CglibClass proxy = (CglibClass)new CglibProxy(cglib).getProxyInstance();
System.out.println(proxy);
proxy.say();
proxy.say1();
proxy.say2();
}
}
4.手写jdk动态代理
package study.proxy.JDKProxyRealization;
/**
* 目标类要实现的接口
* @author an
*
*/
public interface JDKDemoInter {
public void detailShow();
}
package study.proxy.JDKProxyRealization;
/**
* 要被代理的类
* 必须要有实现的接口
* @author an
*
*/
public class JDKClassDemo implements JDKDemoInter{
private String name;
public void detailShow(){
System.out.println("你好我是JDKClassDemo");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package study.proxy.JDKProxyRealization;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
/**
* 代理类的生成实例
* @author an
*
*/
public class ANProxy {
private static final String TR = "\r\n";
//产生代理对象
public static Object getInstance(ANClassLoader classLoader,Class<?> [] interfaces,ANInvocationHandler h) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException, SecurityException{
//生成源代码.java文件 添加实现interfaces接口的文件 并生成各个方法的代理类
String javaStr = generateJavaString(interfaces);
//java文件存储到磁盘
String filePath = ANProxy.class.getResource("").getPath();
File f = new File(filePath+"$Proxy0.java");
try {
FileWriter fw = new FileWriter(f);
fw.write(javaStr);
fw.flush();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
//把生成的.java文件编译成.class文件
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);
Iterable iterable = manager.getJavaFileObjects(f);
JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, null, null, iterable);
task.call();
try {
manager.close();
} catch (IOException e) {
e.printStackTrace();
}
//编译生成的.class文件加载到jvm中来
@SuppressWarnings("rawtypes")
Constructor c =null;
Class proxyClass = classLoader.findClass("$Proxy0");
c = proxyClass.getConstructor(ANInvocationHandler.class);
//删除.java文件
//f.delete();
//返回字节码重组以后的新的代理对象
return c.newInstance(h);
//return null;
}
private static String generateJavaString(Class<?>[] interfaces) {
StringBuilder sb = new StringBuilder();
sb.append("package study.proxy.JDKProxyRealization;"+TR);
sb.append("import study.proxy.JDKProxyRealization.JDKDemoInter;"+TR);
sb.append("import java.lang.reflect.Method;"+TR);
//暂时只实现第一个接口
sb.append("public class $Proxy0 implements "+interfaces[0].getName()+" { "+TR);
sb.append("ANInvocationHandler h;"+TR);
sb.append("public $Proxy0 (ANInvocationHandler h){"+TR);
sb.append(" this.h = h;"+TR);
sb.append("}"+TR);
for(Method m : interfaces[0].getMethods()){
sb.append("public "+m.getReturnType().getName()+" "+m.getName() +"() { "+TR);
sb.append("try {"+TR);
sb.append("Method m ="+interfaces[0].getName()+".class.getMethod(\""+m.getName()+"\",new Class[]{});"+TR);
sb.append("this.h.invoke(this,m,null);"+TR);
sb.append("} catch (Throwable e) {"+TR);
sb.append("e.printStackTrace();"+TR);
sb.append("}"+TR);
sb.append("}"+TR);
sb.append("}"+TR);
}
return sb.toString();
}
}
package study.proxy.JDKProxyRealization;
import java.lang.reflect.Method;
public interface ANInvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
package study.proxy.JDKProxyRealization;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**
* 类加载
* @author an
*
*/
public class ANClassLoader extends ClassLoader{
private File classPathFile;
public ANClassLoader(){
String path = ANClassLoader.class.getResource("").getPath();
this.classPathFile = new File(path);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
String className = ANClassLoader.class.getPackage().getName() + "." + name;
if(classPathFile != null){
File classFile = new File(classPathFile,name.replaceAll("\\.","/") + ".class");
if(classFile.exists()){
FileInputStream in = null;
ByteArrayOutputStream out = null;
try{
in = new FileInputStream(classFile);
out = new ByteArrayOutputStream();
byte [] buff = new byte[1024];
int len;
while ((len = in.read(buff)) != -1){
out.write(buff,0,len);
}
return defineClass(className,out.toByteArray(),0,out.size());
}catch (Exception e){
e.printStackTrace();
}finally {
if(null != in){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(out != null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
return null;
}
}
package study.proxy.JDKProxyRealization;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 代理类
* @author an
*
*/
public class AnProxyClass implements ANInvocationHandler{
private JDKDemoInter obj;
public Object getInstance(JDKDemoInter obj) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException, SecurityException{
this.obj = obj;
Class<?> clazz = obj.getClass();
return ANProxy.getInstance(new ANClassLoader(), clazz.getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
System.out.println("代理前的操作");
method.invoke(this.obj, args);
System.out.println("代理后的操作");
return null;
}
}
package study.proxy.JDKProxyRealization;
import java.lang.reflect.InvocationTargetException;
public class AnProxyTest {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException, SecurityException {
JDKDemoInter ji = (JDKDemoInter)new AnProxyClass().getInstance(new JDKClassDemo());
ji.detailShow();
}
}