代理模式是对象的结构型模式,代码模式给某一个对象提供代理,并由代理对象控制原对象(目标对象,被代理对象)的引用。简单点说,就是经过一个工厂生成一个类的代理对象,当客户端使用的时候不直接使用目标对象,而是直接使用代理对象。代理对象至关于中介.java
public interface UserService { web
public void addUser(String userId,String userName); spring
} ide
public class UserServiceImpl implements UserService {测试
@Overridethis
public void addUser(String userId, String userName) {spa
System.out.println("UserServiceImpl addUser userId->>"+userId);.net
}代理
}对象
(代理类持有被代理类的引用)
public class UserServiceImplProxy implements UserService {
private UserService userService;
public UserServiceImplProxy(UserService userService){
this.userService = userService;
}
@Override
public void addUser(String userId, String userName) {
try {
System.out.println("开始执行:addUser");
userService.addUser(userId, userName);
System.out.println("addUser执行成功。");
} catch (Exception e) {
System.out.println("addUser执行失败。");
}
}
}
public class Client {
public static void main(String[] args) {
UserService userService = new UserServiceImplProxy(new UserServiceImpl());
userService.addUser("001", "centre");
}
}
须要为每个目标类建立一个代理类,须要创建大量的代理类,耦合度高.违背了重复代码只写一次的原则.
Jdk的动态要求目标对象必须实现接口,由于它建立代理对象的时候是根据接口建立的。若是不实现接口,jdk没法给目标对象建立代理对象。被代理对象能够能够实现多个接口,建立代理时指定建立某个接口的代理对象就能够调用该接口定义的方法了
public interface Service {
public void sayHello(String name);
}
public class UserServiceImpl implements UserService ,Service{
@Override
public void addUser(String userId, String userName) {
System.out.println("UserServiceImpl addUser userId->>"+userId);
}
@Override
public void sayHello(String name) {
System.out.println("你好:"+name);
}
}
public class LogHandler implements InvocationHandler {
private Object targertObject;
public Object newInstance(Object targertObject){
this.targertObject = targertObject;
Class targertClass = targertObject.getClass();
return Proxy.newProxyInstance(targertClass.getClassLoader(),
targertClass.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("调用方法"+method.getName());
Object ret = null;
try {
ret = method.invoke(targertObject, args);
System.out.print("成功调用方法:"+method.getName()+";参数为:");
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
} catch (Exception e) {
e.printStackTrace();
System.out.print("调用方法:"+method.getName()+"失败;参数为:");
for (int i = 0; i < args.length; i++) {
System.out.print(args[i]);
}
}
return ret;
}
}
public class Client {
public static void main(String[] args) {
Service Service = (Service)new LogHandler().newInstance(new UserServiceImpl());
UserService userService = (UserService)new LogHandler().newInstance(new UserServiceImpl());
userService.addUser("001", "centre");
Service.sayHello("centre");
}
}
jdk给目标类提供动态要求目标类必须实现接口,当一个目标类不实现接口时,jdk是没法为其提供动态代理的
spring在给某个类提供动态代理时会自动在jdk动态代理和cglib动态代理中动态的选择。使用cglib为目标类提供动态代理:须要导入cglib.jar和asm.jar
若是出现asm中的类没法找到的异常,在java工程中是真的缺乏asm.jar,而在web工程中极可能是asm.jar和spring提供的org.springframework.asm-3.0.4.RELEASE.jar包冲突。
若是一个类继承了某个类,在子类中没有一个方法,用cglib生成该子类的动态代理类中将没有一个方法。
public class CglibProxy implements MethodInterceptor{
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("调用的方法是:" + method.getName());
Object ret = null;
try {
ret = proxy.invokeSuper(obj, args);
System.out.print("成功调用方法:"+method.getName()+";参数为:");
for (int i = 0; i < args.length; i++) {
System.out.print(args[i]);
}
} catch (Exception e) {
e.printStackTrace();
System.out.print("调用方法:"+method.getName()+"失败;参数为:");
for (int i = 0; i < args.length; i++) {
System.out.print(args[i]);
}
}
return ret;
}
}
public class CglibClient {
public static void main(String[] args) {
cglibUse1();
}
public static void cglibUse1(){
Enhancer enhancer = new Enhancer();
// 设置被代理的类(目标类)
enhancer.setSuperclass(UserServiceImpl.class);
//使用回调
enhancer.setCallback(new CglibProxy());
// 创造 代理 (动态扩展了UserServiceImpl类)
UserServiceImpl my = (UserServiceImpl) enhancer.create();
//my.addUser("001", "centre");
int ret = my.addOperter(15, 22);
System.out.println("返回的结果是:"+ret);
}
}
Jdk动态代理要求被代理的类要实现接口,而cglib不须要,cglib能根据内存中为其建立子类(代理对象)
Jdk静态代理能够理解为中介(代理类)知道一切,全部的事情由中介来处理,其余的类完成本身的功能就行了.
jdk动态代理以接口做为媒介,利用反射创建起代理类和被代理类的关系.
CGLib的具体还有点没有理解,但愿能够有人补充.
摘自: http://blog.csdn.net/centre10/article/details/6847828