java中的代理模式与spring中的AOP

来源:互联网 发布:python数据挖掘视频 编辑:程序博客网 时间:2024/05/18 01:23

1.java的代理模式

代理(proxy)是一种设计模式,是属于23种常见设计模式中的一种。谈到设计模式,我们首先想到的是设计模式的几大原则,其中谈论最多的还是单一职责和开闭原则,代理模式实现了对目标对象其他的访问方式,即通过代理对象(proxy)访问目标对象(target)。这样一来,我们可以在目标对象实现的基础上,通过代理对象来对目标对象的功能扩展,它很好地阐释了开闭原则,即对程序的扩展开放,对程序的修改关闭的原则。代理模式在我们生活当中经常遇见,比如租客与房东收房租的关系,房东是房子拥有者,他可以自己带租客看房子,谈价钱等等。但如果房间太多,房东一个人完成不了这么多工作,那么他会聘请中介来帮助他完成这一系列动作,房东只负责签合同和收房费。这时候代理模式就产生了,房东是目标对象,中介就是代理对象。此时,代理模式的主要角色为:目标对象、代理对象。代理对象是对目标对象的扩展,并会调用该目标对象
    -

1.1静态代理

静态代理在实现时,需要定义相关接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类

还是以上面的房屋出为例:两个角色分别为房东(Owner)和中介(Agency),他们共同实现接口Rent
Rent接口如下:

/** * 接口 */public interface Rent {    //出租房屋    void rent();}

目标对象:Owner

/** * 接口实现 * 目标对象 */public class Owner implements Rent {    //重写rent方法    public void rent() {        System.out.println("房东出租房屋");    }}代理对象:Agency

/**
* 代理对象,静态代理
*/
public class Agency implements Rent{
//接收保存目标对象
private Owner owner;
public Agency (Owner owner ){
this.owner =owner ;
}

public void rent() {
owner.rent();//执行目标对象的方法
}
}

测试方法:/** * 测试类 */public class Test {    public static void main(String[] args) {        //目标对象        Owner owner= new Owner();        //代理对象,把目标对象传给代理对象,建立代理关系        Agency agency= new Agency(owner);        agency.rent();//执行的是代理的方法    }}

以上就实现了静态代理案例,它达到了在不修改目标对象的功能前提下,对目标功能扩展,符合了开闭原则,但是如果一旦需要增加接口方法,目标对象与代理对象都要添加相应的代码,这又与开闭原则相违背,那么如何解决如上问题呢?接下来就看动态代理模式


1.2 动态代理

2.1 动态代理的特点
1、代理对象不用实现相关接口
2、代理对象的生成,是通过利用JDK的API,动态的在内存中构建代理对象(仅需要我们指定创建代理对象/目标对象实现的接口的类型即可)

2.2代理对象生成的相关API
需要用到的类:java.lang.reflect.Proxy
JDK实现代理需要使用newProxyInstance()这个方法,但是该方法需要接收三个参数,具体的实现是:
static Object newProxyInstance(ClassLoader loader, Class

/** * 创建动态代理对象 * 动态代理不需要实现接口,但是需要指定接口类型 */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("操作1");                        //执行目标对象方法                        Object returnValue = method.invoke(target, args);                        System.out.println("操作2");                        return returnValue;                    }                }        );    }}

可以编写测试类来测试:

/** * 测试类 */public class Test {    public static void main(String[] args) {        // 目标对象        IUserDao target = new UserDao();        System.out.println(target.getClass());        // 给目标对象,创建代理对象        Agency agency= (Agency) new ProxyFactory(Owner).getProxyInstance();        // class $Proxy0   内存中动态生成的代理对象        System.out.println(agency.getClass());        // 执行方法   【代理对象】        agency.rent();    }}

以上就是Java的动态代理,总结:Java动态代理对象不需要实现接口,但是目标对象(Owner对象)一定要实现接口,否则不能用动态代理

spring中的AOP

AOP和IOC组成了spring的重要两大思想,AOP即面向切面编程,它应用于项目中的日志功能,权限管理,事物等等。这些功能代码都直接切入地在该对象层次中,而与它对应的对象的核心代码没有关系,这种散布在各处的无关的代码被称为横切(cross cutting)。剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为”Aspect”,即切面。切面与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用”横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

原创粉丝点击