Spring学习记录(下)

阅读: 评论:0

Spring学习记录(下)

Spring学习记录(下)

文章目录

  • 8、代理模式
    • 8.1、静态代理
    • 8.2、动态代理
  • 9、AOP
    • 9.1 使用Spring实现AOP
      • 9.1.1 使用Spring的API接口【接口实现】
      • 9.1.2 自定义实现【切面定义】
      • 9.1.3 注解实现

前文:Spring学习记录(上)

8、代理模式

为什么要学习代理模式?因为Spring底层中随处可见

【SpringAOP】和【SpringMVC】面试必问

两种代理模式:

  • 静态代理
  • 动态代理

8.1、静态代理

角色分析:

  • 抽象角色:一般使用抽象类或接口实现
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色,代理后一般会做一些附属操作
  • 客户:访问代理对象的人

代码步骤:

  • 接口

    public interface UserService {void addUser();void deleteUser();void updateUser();void selectUser();
    }
    
  • 真实角色

    public class UserServiceImpl implements UserService{@Overridepublic void addUser() {System.out.println("新增了一个用户");}@Overridepublic void deleteUser() {System.out.println("删除了一个用户");}@Overridepublic void updateUser() {System.out.println("修改了一个用户");}@Overridepublic void selectUser() {System.out.println("查找了一个用户");}
    }
  • 代理角色

    public class UserServiceProxy implements UserService{UserService userService;public void setUserService(UserService userService) {this.userService = userService;}@Overridepublic void addUser() {log("add");userService.addUser();}@Overridepublic void deleteUser() {log("delete");userService.deleteUser();}@Overridepublic void updateUser() {log("update");userService.updateUser();}@Overridepublic void selectUser() {log("select");userService.selectUser();}//新增的业务private void log(String msg){System.out.println("[Debug] "+ msg);}
    }
    
  • 客户端访问代理角色

    public class Client {public static void main(String[] args) {UserServiceImpl userService=new UserServiceImpl();UserServiceProxy proxy=new UserServiceProxy();proxy.setUserService(userService);proxy.addUser();}
    }
    

代理模式的好处:

  • 首先,在公司开发时修改之前的业务代码是大忌,所以新增代理角色。
  • 可以使真实角色的操作更纯粹,不用去关注公共的业务
  • 公共业务就交给代理角色,实现业务的分工。
  • 公共业务拓展时,方便集中管理

缺点:

  • 一个真实角色就要产生一个代理角色,代码量翻倍,开发效率变低

8.2、动态代理

  • 动态代理和静态代理的角色是相同的
  • 动态代理的代理类是动态生成的,不是我们直接写好的!
  • 动态代理分为两种:
    • 基于接口:JDK动态代理【在此我们使用这个】
    • 基于类:cglib
    • java字节码实现:javasist

需要了解两个类:Proxy:代理,InvocationHandler:调用处理程序

动态生成代理类的处理程序:

public class ProxyInvocationHandler implements InvocationHandler {//被代理的接口private Object target;public void setTarget(Object target) {this.target = target;}//生成得到代理类public Object getProxy() {Class().getClassLoader(), Class().getInterfaces(), this);}//处理代理实例,并返回结果@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//例子Name());//动态代理本质上是使用反射机制实现return method.invoke(target, args);}//例子private void log(String msg) {System.out.println("[Debug] " + msg);}
}

使用:

public static void main(String[] args) {//真实对象UserServiceImpl userService=new UserServiceImpl();//通过代理处理程序生成ProxyInvocationHandler pih=new ProxyInvocationHandler();//1.设置要代理的对象pih.setTarget(userService);//2.动态生成代理类UserService proxy = (UserService) Proxy();proxy.deleteUser();}

动态代理的好处:

  • 可以使真实角色的操作更纯粹,不用去关注公共的业务
  • 公共业务就交给代理角色,实现业务的分工。
  • 公共业务拓展时,方便集中管理
  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务
  • 一个动态代理类可以代理多个类,只要是实现了同一个接口的类

9、AOP

AOP(Aspect Oriented Programming),意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率

AOP可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

AOP技术恰恰相反,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

作者:Tiffany_弥弥
链接:
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

9.1 使用Spring实现AOP

Maven

<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.7</version><scope>runtime</scope>
</dependency>

9.1.1 使用Spring的API接口【接口实现】

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=""xmlns:xsi=""xmlns:aop=""xsi:schemaLocation="://www.springframework/schema/beans/spring-beans.xsd://www.springframework/schema/aop/spring-aop.xsd
"><bean id="userService" class="com.zhanc.service.UserServiceImpl"/><bean id="log" class="com.zhanc.log.Log"/><bean id="afterLog" class="com.zhanc.log.AfterLog"/><!--方式一:使用原生Spring API接口--><!--配置aop--><aop:config><!--切入点:expression:表达式,excution(要执行的位置! *(修饰词) *(返回值) *(列名) *(方法名) *(参数))--><aop:pointcut id="pt1" expression="execution(* com.zhanc.service.UserServiceImpl.*(..))"/><!--执行环绕增加--><aop:advisor advice-ref="log" pointcut-ref="pt1"/><aop:advisor advice-ref="afterLog" pointcut-ref="pt1"/></aop:config></beans>

9.1.2 自定义实现【切面定义】

自定义类:

public class DiyPointCut {public void before(){System.out.println("==========执行前");}public void after(){System.out.println("==========执行后");}
}
...
<bean id="diyPointCut" class="com.zhanc.diy.DiyPointCut"/>
<!--方式二:使用自定义类-->
<aop:config><aop:pointcut id="pt1" expression="execution(* com.zhanc.service.UserServiceImpl.*(..))"/><!--自定义切面,ref-要引用的自定义类--><aop:aspect ref="diyPointCut"><aop:before method="before" pointcut-ref="pt1"/><aop:after method="after" pointcut-ref="pt1"/></aop:aspect>
</aop:config>
...

9.1.3 注解实现

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=""xmlns:xsi=""xmlns:aop=""xmlns:context=""xsi:schemaLocation="://www.springframework/schema/beans/spring-beans.xsd://www.springframework/schema/aop/spring-aop.xsd://www.springframework/schema/context/spring-context.xsd"><!--指定要扫描的包,这个包下的注解就会生效--><context:component-scan base-package="com.zhanc"/><!--开启注解支持--><context:annotation-config/><aop:aspectj-autoproxy/>...
</beans>

自定义注解切点类:

@Component
@Aspect
public class AnnotationPointCut {@Before("execution(* com.zhanc.service.UserServiceImpl.*(..))")public void before(){System.out.println("----------方法前");}@After("execution(* com.zhanc.service.UserServiceImpl.*(..))")public void after(){System.out.println("----------方法后");}
}

本文发布于:2024-02-02 13:04:30,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170685027143988.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:Spring
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23