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的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。