代理模式
静态代理
基本介绍:
静态代理在使用中,需要定义接口或者父类,被代理对象(目标对象)与代理对象一起实现相同的接口或者是继承相同的父类。
实例:
uml类图:

代码:
ITeacherDao:
public interface ITeacherDao {
/**
* teach方法
*/
void teach();
}
TeacherDaoImpl:
public class TeacherDaoImpl implements ITeacherDao {
@Override
public void teach() {
System.out.println("teacher is working");
}
}
TeacherDaoProxy :
public class TeacherDaoProxy implements ITeacherDao {
// 目标对象 通过接口来聚合
/**
* target
*/
private final ITeacherDao target;
public TeacherDaoProxy(ITeacherDao target){
this.target=target;
}
@Override
public void teach() {
System.out.println("proxy is working");
//目标的核心代码
target.teach();
System.out.println("proxy is over");
}
}
client:
@Test
public void test1(){
TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy( new TeacherDaoImpl());
teacherDaoProxy.teach();
}
优点:在不修改目标对象功能的情况下,能通过代理对象对目标功能进行扩展
缺点:
-
因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类
-
一旦接口增加方法,目标对象和代理对象都要维护
动态代理
基本介绍:
-
代理对象,不需要实现接口,但是目标对象要实现接口,否者不能用动态代理
-
代理对象的生成,利用jdk的API,动态的在内存中构建代理对象
-
动态代理也叫做:JDK代理,接口代理
UML图:

代码:
ITeacherDao:
public interface ITeacherDao {
/**
* teach方法
*/
void teach();
/**
*
* @param a a
* @param b b
* @return int
*/
int count(int a,int b);
}
TeacherDaoImpl:
public class TeacherDaoImpl implements ITeacherDao {
@Override
public void teach() {
System.out.println("teacher is working");
}
@Override
public int count(int a, int b) {
System.out.println("开始计算");
return a+b;
}
}
ProxyFactory:
public class ProxyFactory {
private Object target;
public ProxyFactory(Object target){
this.target=target;
}
public Object getProxyInstance(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK代理开始");
Object returnVal = method.invoke(target, args);
System.out.println("jdk动态代理结束");
return returnVal;
}
});
}
}
client:
@Test void Test3(){
//创建目标对象
ITeacherDao teacherDao = new TeacherDaoImpl();
//给目标对象创建代理对象
ITeacherDao teacher=(ITeacherDao ) new ProxyFactory(teacherDao).getProxyInstance();
teacher.teach();
int a=teacher.count(2,5);
System.out.println(a);
}
cglib代理
-
静态代理和jDK代理模式都要求目标对象实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候可使用目标对象子类来实现代理-这就是cglib代理。
-
Cglib代理也叫做子类代理,他是在内存中构建一个子类对象从而实现目标对象功能扩展,cglib代理也可以归类到动态代理
-
Cglib代理是一个强大的高性能的代码生成包,它可以在运行期间扩展java类与实现java的接口,他广泛的被许多AOP框架使用,例如Spring AOP,实现方法拦截
-
在AOP编程中如何选择代理模式: a. 目标对象需要实现接口,用JDK代理
b. 目标对象不需要实现接口,用Cglib代理
-
Cglib包底层是通过使用字节码处理框架ASM来转换字节码生成新的类
UML图:

代码:
Teacher:
public class Teacher {
public void teach() {
System.out.println("teacher is working");
}
public Integer count(int a,int b){
return a+b;
}
}
ProxyFactory:
public class ProxyFactory implements MethodInterceptor {
//维护一个目标对象
private Object target;
public ProxyFactory(Object target){
this.target=target;
}
//返回一个代理对象,是target的代理对象
/**
*
* @return Object
*/
public Object getProxyInstance(){
//创建一个工具类
Enhancer enhancer=new Enhancer();
//设置父类
enhancer.setSuperclass(target.getClass());
//设置回调函数
enhancer.setCallback(this);
//创建子类对象,及代理对象
return enhancer.create();
}
// 重写
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib代理开始");
Object re = method.invoke(target, objects);
System.out.println("cglib提交");
return re;
}
}
client:
@Test
void test3(){
//
Teacher target=new Teacher();
ProxyFactory proxyFactory=new ProxyFactory(target);
Teacher teacher = (Teacher) proxyFactory.getProxyInstance();
teacher.teach();
System.out.println(teacher.count(4,5));
}
本文介绍了静态代理模式,如Java中的静态代理,通过接口或父类实现目标对象的功能扩展,包括了UML类图和代码示例。接着探讨了动态代理,特别是JDK代理(基于接口)和Cglib代理(针对无接口对象),并提供了相应的代码和优缺点分析。
1582

被折叠的 条评论
为什么被折叠?



