代理模式
代理模式就是多一个代理类出来,替原对象进行一些操作,比如我们在租房子的时候回去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你做,此处的代理就是这个意思。再如我们有的时候打官司,我们需要请律师,因为律师在法律方面有专长,可以替我们进行操作,表达我们的想法。代理模式在spring aop中有重要应用的应用。
public interface Sourceable {
public void method();
}
public class Source implements Sourceable {
@Override
public void method() {
System.out.println("the original method!");
}
}
如果我们想在method方法前面进行加入方法。我们可以直接修改原来的方法。但是根据ocp原则,我们应该对扩展开放,对修改关闭。
public class Proxy implements Sourceable {
private Source source;
public Proxy(){
super();
this.source = new Source();
}
@Override
public void method() {
before();
source.method();
atfer();
}
private void atfer() {
System.out.println("after proxy!");
}
private void before() {
System.out.println("before proxy!");
}
}
public class ProxyTest {
public static void main(String[] args) {
Sourceable source = new Proxy();
source.method();
}
}
before proxy!
the original method!
after proxy!
再谈谈动态代理和ciglib代理。
所以jdk代理是需要实现接口而CGLIB代理是不需要的。
jdk代理
jdk代理一定要实现接口,代理的包都是jdk自带的。而cglib代理是一个开源项目是需要引进第三方包的。
public interface UserService {
public String getName();
public Integer getAge();
}
public class UserServiceImpl implements UserService {
@Override
public String getName() {
System.out.println("-------------getName------------");
return "Tom";
}
@Override
public Integer getAge() {
System.out.println("----------getAge-----------");
return 10;
}
}
代理实现
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private Object target;
MyInvocationHandler() {
super();
}
MyInvocationHandler(Object target) {
super();
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if ("getName".equals(method.getName())) {
System.out.println("++++++before " + method.getName() + "++++++");
Object result = method.invoke(target, args);
System.out.println("++++++after " + method.getName() + "++++++");
return result;
} else {
Object result = method.invoke(target, args);
return result;
}
}
}
测试
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
InvocationHandler invocationHandler = new MyInvocationHandler(userService);
UserService userServiceProxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(), invocationHandler);
System.out.println(userServiceProxy.getName());
System.out.println("分割线-----------------------------------------");
System.out.println(userServiceProxy.getAge());
}
}
结果是:
++++++before getName++++++
————-getName————
++++++after getName++++++
Tom
分割线—————————————–
———-getAge———–
10
ciglib代理是不需要实现接口,要引入第三方类库。
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("++++++before " + methodProxy.getSuperName() + "++++++");
System.out.println(method.getName());
Object o1 = methodProxy.invokeSuper(o, args);
System.out.println("++++++before " + methodProxy.getSuperName() + "++++++");
return o1;
}
}
import net.sf.cglib.proxy.Enhancer;
public class Main2 {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserServiceImpl.class);
enhancer.setCallback(cglibProxy);
UserService o = (UserService)enhancer.create();
o.getName();
o.getAge();
}
}
结果是:
++++++before CGLIB getName 0++++++
getName
——getName——
++++++before CGLIB getName 0++++++
++++++before CGLIB getAge 1++++++
getAge
——getAge——
++++++before CGLIB getAge 1++++++