什么是代理模式
代理模式是一种常见的设计模式,它提供间接对目标对象访问的方式,通过代理对象访问目标对象,从而在在目标对象现有的功能能上,增加额外的功能补充,实现扩展目标对象的功能。
代理模式又分为静态代理和动态代理。
静态代理:静态代理是代理模式的实现方式之一,在程序运行前,手动创建代理类,从而实现对目标类中的方法进
行增强
动态代理:动态生成映射接口的一个实现类对象,该对象可以使用实现xml文件的sql语句结合封装的JDBC代码来实现数据库的交互。
动态代理分为JDK动态代理和CGLIB代理
JDK:目标类对象一定要实现一个接口。newInsatance产生动态代理对象需要三个对象:目标类的类加载器,目标类的接口(反射技术实现),匿名内部类实现InvocationHandler接口
// 目标类对象
Singer ts = new TargetSinger("mary");
// 获得Class对象
Class<?> clazz = ts.getClass();
// 获得类加载器
ClassLoader classLoader = clazz.getClassLoader();
// 获得目标类所实现的接口
Class<?>[] interfaces = clazz.getInterfaces();
// 使用匿名内部类实现InvocationHandler接口
InvocationHandler handler = new InvocationHandler() {
/*
* proxy 代理类对象
* method 要增强的方法(调用目标类的方法)
* args 调用目标类方法的参数
*
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("联系场地(proxy)");
System.out.println("签订合同(proxy)");
System.out.println("组织安保(proxy)");
// 调用目标类的核心功能
Object result = method.invoke(ts, args);
System.out.println("费用结算(proxy)");
return result;
}
};
AOP
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
简单来说,将程序中重复的代码抽取出来,在程序执行的时候,利用动态代理技术,在不修改源码的基础上,把抽取出来的代码,在重新织入到原有的程序中,对现有的功能进行动态的增强
xml文件中需要配置
<!-- 配置代理类 -->
<bean id="teacher" class="com.briup.aop.TeacherServiceImpl"></bean>
<!-- 配置切面类 -->
<bean id="myAspect" class="com.briup.aop.MyAspect"></bean>
<!-- 配置AOP -->
<aop:config>
<!--
配置切入点
实际上就是定义一些方法的集合
id 切入点的唯一标识
expression 选择切入点的表达式
-->
<aop:pointcut id="allMethod" expression="execution(* com.briup.aop..*.*(..))"/>
<aop:pointcut id="deleteMethod" expression="execution(* com.briup.aop.ITeacherService.delete*())"/>
<!--
配置通知织入
id 切面的唯一标识
ref 引用上面定义好的切面类的bean
-->
<aop:aspect id="aspect" ref="myAspect">
<!-- 前置通知 -->
<!--
method 在切面类中定义的公共方法
pointcut-ref 上面定义的切入点的唯一标识
-->
<aop:before method="before" pointcut-ref="allMethod"/>
<!-- 后置通知 -->
<aop:after-returning method="afterReturn" pointcut-ref="allMethod"/>
<!-- 最终通知 -->
<aop:after method="after" pointcut-ref="deleteMethod"/>
<!-- 异常通知 -->
<aop:after-throwing method="throwable" pointcut-ref="deleteMethod"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="allMethod"/>
</aop:aspect>
</aop:config>