java–代理模式
代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象。这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。
- 举个例子来说明代理的作用:假设我们想邀请一位明星,那么并不是直接连接明星,而是联系明星的经纪人,来达到同样的目的。明星就是一个目标对象,他只要负责活动中的节目,而其他琐碎的事情就交给他的代理人(经纪人)来解决。这就是代理思想在现实中的一个例子,如图所示:
银行存钱转账实例:
接口:
package cn.zbw.dao;
public interface BankDao {
public void saveMoney();
public void transferAccounts();
}
接口实现类:
package cn.zbw.dao.impl;
import cn.zbw.dao.BankDao;
public class BankDaoImpl implements BankDao {
@Override
public void saveMoney() {
System.out.println("我正在存钱");
}
@Override
public void transferAccounts() {
System.out.println("我正在转账");
}
}
业务逻辑代码:
(1)验证:
package cn.zbw.dao.impl;
public class AdminCheck {
public void check(){
System.out.println("开始验证");
}
}
(2)事务:
package cn.zbw.dao.impl;
public class AffairInfo {
public void begin(){
System.out.println("开始业务");
}
public void commit(){
System.out.println("提交业务");
}
}
(3)日志:
package cn.zbw.dao.impl;
public class LogInfo {
public void writeLog(){
System.out.println("记录日志");
}
}
代理:
(1)验证:
package cn.zbw.interceptor;
import cn.zbw.dao.impl.AdminCheck;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.lang.Nullable;
import java.lang.reflect.Method;
public class AdminCheckInter implements MethodBeforeAdvice {
private AdminCheck adminCheck;
public AdminCheckInter(AdminCheck adminCheck) {
this.adminCheck = adminCheck;
}
public AdminCheckInter() {
}
public AdminCheck getAdminCheck() {
return adminCheck;
}
public void setAdminCheck(AdminCheck adminCheck) {
this.adminCheck = adminCheck;
}
@Override
public void before(Method method, Object[] objects, @Nullable Object o) throws Throwable {
adminCheck.check();
}
}
(2)日志:
package cn.zbw.interceptor;
import cn.zbw.dao.impl.LogInfo;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.lang.Nullable;
import java.lang.reflect.Method;
public class LogInfoInter implements AfterReturningAdvice {
private LogInfo logInfo;
public LogInfoInter(LogInfo logInfo) {
this.logInfo = logInfo;
}
public LogInfoInter() {
}
public LogInfo getLogInfo() {
return logInfo;
}
public void setLogInfo(LogInfo logInfo) {
this.logInfo = logInfo;
}
@Override
public void afterReturning(@Nullable Object o, Method method, Object[] objects, @Nullable Object o1) throws Throwable {
logInfo.writeLog();
}
}
(3)事务:
package cn.zbw.interceptor;
import cn.zbw.dao.BankDao;
import cn.zbw.dao.impl.AffairInfo;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class BankDaoInter implements MethodInterceptor {
private AffairInfo affairInfo;
public BankDaoInter(AffairInfo affairInfo) {
this.affairInfo = affairInfo;
}
public BankDaoInter() {
}
public AffairInfo getAffairInfo() {
return affairInfo;
}
public void setAffairInfo(AffairInfo affairInfo) {
this.affairInfo = affairInfo;
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
affairInfo.begin();
Object obj = invocation.proceed();
affairInfo.commit();
return obj;
}
}
xml 文件配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<bean id="adminCheck" class="cn.zbw.dao.impl.AdminCheck"></bean>
<bean id="logInfo" class="cn.zbw.dao.impl.LogInfo"></bean>
<bean id="affairInfo" class="cn.zbw.dao.impl.AffairInfo"></bean>
<!--代理目标-->
<bean id="bankDao" class="cn.zbw.dao.impl.BankDaoImpl"></bean>
<!--通知组建-->
<bean id="adminCheckInter" class="cn.zbw.interceptor.AdminCheckInter">
<property name="adminCheck" ref="adminCheck"></property>
</bean>
<bean id="logInfoInter" class="cn.zbw.interceptor.LogInfoInter">
<property name="logInfo" ref="logInfo"></property>
</bean>
<bean id="bankDaoInter" class="cn.zbw.interceptor.BankDaoInter">
<property name="affairInfo" ref="affairInfo"></property>
</bean>
<bean id="bankProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--代理对象-->
<property name="target" ref="bankDao"></property>
<!--代理接口-->
<property name="interfaces" value="cn.zbw.dao.BankDao"></property>
<!--代理通知-->
<property name="interceptorNames">
<list>
<value>adminCheckInter</value>
<value>logInfoInter</value>
<value>bankDaoInter</value>
</list>
</property>
</bean>
</beans>
测试:
package cn.zbw.test;
import cn.zbw.dao.BankDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test01 {
public static void main(String[] args) {
test1();
}
private static void test1() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
BankDao bd = (BankDao) ac.getBean("bankProxy");
System.out.println(bd.getClass().getName());
bd.saveMoney();
}
}
结果是: