静态代理StaticProxy.java
package com.csdn.proxy;
/**
* 静态代理
* 对原有类的现有方法进行增强,静态代理还是比较容易理解的
* 要素:
* 1.共同的接口或者抽象类
* 2.原有类(必须实现共同的接口或者继承共同的抽象类)
* 3.代理类(必须实现共同的接口或者继承共同的抽象类,且要想办法把原有类对象传过去,用依赖倒置原则)
* 代理模式常用于:
* 1.日志记录
* 2.事务处理
*/
//共同的接口类(推荐尽量多的用接口,面向接口编程)
interface CommonAction{
public void method();
}
//原有类实现共同的接口类
class MyClass implements CommonAction{
@Override
public void method() {
System.out.println("这是我原有的方法");
}
}
//代理类实现共同的接口类,并把原有类当成类属性,通过构造方法参数值传过来
class Proxy implements CommonAction{
CommonAction object;
public Proxy(CommonAction object) {
this.object = object;
}
@Override
public void method() {
this.before();
object.method();
this.after();
}
private void before(){
System.out.println("做事之前记日志");
}
private void after(){
System.out.println("做事之后记日志");
}
}
public class StaticProxy {
public static void main(String[] args) {
CommonAction old = new MyClass();
//此时就对原有类中的方法进行了增强
CommonAction proxy = new Proxy(old);
proxy.method();
}
}
jdk动态代理 JdkProxy.java
package com.csdn.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 动态代理:代理类动态生成
* jdk动态代理:提供一个中间类handler,这个中间类必须实现InvocationHandler接口,要实现其中的invoke方法
* 而后使用时,jdk的reflect包中的Proxy会提供调用这个中间类的方法,这个方法的返回对象为代理类对象
*/
//共同的接口类(推荐尽量多的用接口,面向接口编程)
interface CommonAction1{
public void method();
}
//原有类实现共同的接口类
class MyClass1 implements CommonAction1{
@Override
public void method() {
System.out.println("这是我原有的方法");
}
}
//jdk动态代理的中间类,必须实现InvocationHandler接口,实现invoke方法
//注意:这个类并不是真正的代理类。只是真正的代理类是由它生成的
//具体如何调用,由jdk说了算。jdk是用反射包中的Proxy.new开头(newProxyInstance)的方法 来实现的
class DynamicProxyHandler implements InvocationHandler {
CommonAction1 object;
public DynamicProxyHandler(CommonAction1 object) {
this.object = object;
}
private void before(){
System.out.println("做事之前记日志");
}
private void after(){
System.out.println("做事之后记日志");
}
/**
*
* @param proxy 生成的动态代理对象
* @param method 要代理的方法
* @param args 要代理的方法参数
* @return 要代理的方法执行完成后返回的参数
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.before();
method.invoke(this.object,args);
this.after();
return null;
}
}
public class JdkProxy {
public static void main(String[] args) {
ClassLoader classLoader = CommonAction1.class.getClassLoader();
//中间类对象。注意把原有类对象通过构造方法也可以通过set方法传进去
DynamicProxyHandler handler = new DynamicProxyHandler(new MyClass1());
//第1个参数为类加载器(动态生成的代理类到时用什么加载器加载)
//第2个参数共同的接口的class(字节码对象),为动态生成的代理类与原有类都实现的同一个接口
//第3个参数为jdk要求的InvocationHandler接口的实现类
//返回对象为动态代理类的对象
CommonAction1 proxy = (CommonAction1)java.lang.reflect.Proxy.newProxyInstance(classLoader,new Class[]{CommonAction1.class},
handler);
//调用动态代理对象的方法
proxy.method();
}
}
cglib动态代理CglibProxy.java
package com.csdn.proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* cglib动态代理。与jdk动态代理实现类似。只是jdk是基于接口的,但cglib是基于继承的(方法)
* 要素:
* 1.原始类(不能用final修饰)
* 2.handler类,继承于cglib的MethodInterceptor类
* 3.生成代理类并调用
* 具体代理的是类中的哪个方法,由原有类调用时调用哪个方法来决定
* 必须要导入2个jar包
* 1)cglib-2.2.2.jar
* 2)asm-3.3.1.jar(不要忘了)
*/
class OldClass{
public void myMethod1(){
System.out.println("我的第1个方法");
}
public void myMethod2(){
System.out.println("我的第2个方法");
}
}
class CglibProxyHandler implements MethodInterceptor {
/**
* 类似于jdk的invoke方法
* @param o 代理类对象
* @param method 原始类中某方法
* @param objects 原始类中的某方法参数
* @param methodProxy 代理类类对象中的代理方法
* @return 代理类的对象
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglig:前置增强");
System.out.println(o.getClass());
Object object = methodProxy.invokeSuper(o, objects);
System.out.println("cglig:后置增强");
System.out.println(methodProxy.getSuperName());
return object;
}
}
public class CglibProxy {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
//设置需要被代理的对象
enhancer.setSuperclass(OldClass.class);
//设置hander
enhancer.setCallback(new CglibProxyHandler());
OldClass o = (OldClass)enhancer.create();
//调用哪个方法,就对哪个方法进行增强
o.myMethod2();
}
}