当前位置: 首页 > Web前端 > JavaScript

Java必看的Spring知识总结!

时间:2023-03-27 13:49:09 JavaScript

Spring框架是由于软件开发的复杂性而产生的。Spring使用基本的JavaBeans来做以前只有EJB才能做的事情。然而,Spring的使用并不局限于服务器端开发。从简单性、可测试性和松散耦合的角度来看,大多数Java应用程序都可以从Spring中受益。Spring的优点:低侵入式设计,极低的代码污染;独立于各种应用服务器,基于Spring框架的应用能够真正实现WriteOnce,RunAnywhere的承诺;Spring的IoC容器降低了业务对象替换的复杂度,提高了组件之间的解耦。Spring的AOP支持允许集中管理一些通用任务,如安全、事务、日志等,从而提供更好的重用;Spring的ORM和DAO提供了第三方持久化层框架的良好集成,简化了底层的数据库访问;pring的高开放性并没有迫使应用程序完全依赖Spring,开发者可以自由选择部分或全部Spring框架。Spring框架结构图:Spring的核心机制管理bean程序主要是通过Spring容器访问容器中的bean。ApplicationContext是Spring容器最常用的接口。该接口有如下两个实现类:ClassPathXmlApplicationContext:从类加载路径中搜索配置文件,根据配置文件创建Spring容器;FileSystemXmlApplicationContext:从文件系统的相对路径或绝对路径中查找配置文件,根据配置文件创建Spring容器;Personp=ctx.getBean(“person”,Person.class);说;EclipseUsingSpring在Eclipse等IDE工具中,用户可以构建自己的UserLibrary,然后将所有的SpringJar包放入其中。当然你也可以将Jar包直接放在项目的/WEB-INF/lib目录下,但是如果使用UserLibrary,需要在项目发布时添加用户库引用的Jar文件。随应用发布就是将UserLibrary使用的Jar复制到/WEB-INF/lib目录下。这是因为对于一个web应用程序,Eclipse在部署web应用程序时,不会将用户库的Jar文件复制到/WEB-INF/lib中。在INF/lib下,需要手动复制。依赖注入有两个Spring框架的核心功能:作为一个超级工厂,Spring容器负责创建和管理所有的Java对象,这些对象被称为bean;Spring容器管理容器中bean之间的依赖关系,Spring使用一种叫做“依赖注入”的方式来管理bean之间的依赖关系。使用依赖注入,不仅可以将普通的属性值注入到bean中,还可以注入其他bean的引用。依赖注入是一种很好的解耦方式,它允许bean在配置文件中组织在一起,而不是以硬编码的方式耦合在一起。理解依赖注入RodJohnson是第一个非常重视由配置文件管理的Java实例的协作关系的人。他给这个方法起了个名字:控制反转(InverseofControl,IoC)。后来MartineFowler给这个方法起了另外一个名字:依赖注入(DependencyInjection),所以不管是依赖注入还是控制反转,其含义是完全一样的。当一个Java对象(调用者)需要调用另一个Java对象(依赖对象)的方法时,传统模式下通常有两种方法:原始方法:调用者主动创建依赖对象,然后调用依赖对象的方法;简单工厂模式:调用者先找到依赖对象的工厂,然后通过工厂主动获取依赖对象,最后调用依赖对象的方法。注意上面的“主动”二字,这必然会导致调用者和依赖对象实现类的硬编码耦合,非常不利于项目升级的维护。使用Spring框架后,调用者无需主动获取依赖对象。调用者只需要被动接受Spring容器为调用者的成员变量赋值即可。可以看出,使用Spring之后,调用者获取依赖对象的方式从原来的主动获取变成了被动接受——所以RodJohnson称之为控制反转。另外,从Spring容器的角度来看,Spring容器负责将依赖对象赋值给调用者的成员变量——相当于为调用者注入它所依赖的实例,所以MartineFowler称之为依赖注入。设置值注入设置值注入是指IoC容器通过成员变量的setter方法注入依赖对象。这种注入方式简单直观,因此在Spring的依赖注入中被广泛使用。构造注入使用构造器设置依赖的方法称为构造注入。通俗地说,就是驱动Spring在底层反射式地执行指定参数的构造函数。当执行带参数的构造函数时,可以用构造函数参数初始化成员变量——这就是构造注入的本质。两种注入方式比较:setvalueinjection有以下优点:更类似于传统的JavaBean写法,更容易被程序开发人员理解和接受。通过setter方法设置依赖更加直观自然;对于复杂的依赖,如果使用构造注入,构造函数会过于臃肿,难以阅读。Spring在创建Bean实例时,需要同时实例化它所依赖的所有实例,导致性能下降。使用setvalueinjection可以避免这些问题。尤其是在一些成员变量是可选的情况下,多参数构造函数就比较繁琐了。构造注入的优点是:构造注入可以决定构造函数中依赖的注入顺序,依赖注入的优先级优先;对于不需要改变依赖关系的bean,构造注入更有用。因为没有setter方法,所有依赖都在构造函数中设置,不用担心后续代码破坏依赖;dependencies只能在构造函数中设置,只有组件的创建者才能改变组件的依赖关系,对于组件的调用者来说,组件内部的依赖是完全透明的,更符合高凝聚力。Notes推荐使用设置值注入为主,结构体注入为辅的注入策略。对于不需要改变依赖的注入,尽量使用构造注入;而对于其他依赖的注入,可以考虑使用set值注入。Spring容器中的Bean对于开发者来说,开发者使用Spring框架主要做两件事:①开发bean;②配置bean。对于Spring框架来说,它要做的就是根据配置文件创建一个Bean实例,并调用Bean实例的方法来完成“依赖注入”——这就是所谓IoC的本质。bean在容器中的作用域通过Spring容器创建bean实例时,不仅可以完成bean实例的实例化,还可以为bean指定一个具体的作用域。Spring支持以下五种作用域:singleton:单例模式,在整个SpringIoC容器中,一个单例作用域的bean只会生成一个实例;prototype:每次通过容器的getBean方法获取一个prototype作用域的bean,都会生成一个新的Bean实例;request:对于一次HTTP请求,只会生成请求范围内的一个Bean实例,也就是说在同一个HTTP请求中,程序每次请求Bean,总是会得到同一个实例。这个作用域只有在web应用中使用Spring时才有效;对于一个HTTP会话,只会生成一个会话范围的bean实例,这意味着在同一个HTTP会话中,每次程序请求该bean,你总是得到同一个实例。只有在Web应用程序中使用Spring时,此范围才真正有效;globalsession:每个全局HTTPSession对应一个Bean实例。在典型情况下,它仅在使用portlet上下文时有效,也仅在Web应用程序中有效。如果不指定bean的作用域,Spring默认使用单例作用域。在原型范围内创建和销毁bean的成本相对较高。一旦创建了单例范围的Bean实例,就可以重用它。因此,您应该尽量避免将Bean设置为原型作用域。使用自动组装注入伙伴BeanSpring可以自动组装Bean与Bean之间的依赖关系,即不需要使用ref显式指定依赖的Bean,而是Spring容器检查XML配置文件的内容,以及DependentBean按照一定的规则注入callerBean。可以通过元素的default-autowire属性指定Spring自动装配,该属性适用于配置文件中的所有bean;也可以通过元素的autowire属性指定,该属性仅对bean有效。autowire和default-autowire可以接受以下值:no:不使用自动装配。Bean依赖项必须通过ref元素定义。这是默认配置。不鼓励在大型部署环境中更改此配置。显式配置协作者可以获得更清晰的依赖关系;byName:根据setter方法的名字自动组装。Spring容器搜索容器内所有的bean,找出id和setter方法名去掉set前缀的bean,将同名bean的首字母小写,完成注入。如果没有找到匹配的Bean实例,Spring将不会执行任何注入;byType:根据setter方法的形参类型自动装配。Spring容器搜索容器中的所有bean。如果恰好有一个bean类型匹配setter方法的形参类型,则自动注入该bean;如果找到多个这样的bean,则抛出异常;如果没有找到这样的bean,则什么也不会发生,也不会调用setter方法;constructor:与byType类似,不同的是用于自动匹配构造函数的参数。如果容器找不到符合构造函数参数类型的Bean,就会抛出异常;autodetect:Spring容器根据Bean的内部结构决定使用constructor还是byType策略。如果找到默认构造函数,则应用byType策略。当一个bean同时使用自动装配依赖和ref来显式指定依赖时,显式指定的依赖会覆盖自动装配依赖;对于大型应用程序,不鼓励使用自动装配。使用自动装配虽然可以减少配置文件的工作量,但是却大大降低了依赖关系的清晰度和透明度。依赖的组装依赖于源文件的属性名和属性类型,将Bean与Bean之间的耦合降低到代码层面,不利于高层解耦;创建bean的三种方式:使用构造函数创建bean实例使用构造函数创建bean实例是最一般情况下,如果不使用构造注入,Spring底层会调用Bean类的无参构造函数来创建实例,所以需要Bean类提供无参构造函数。使用默认构造函数创建Bean实例,Spring对Bean实例的所有属性进行默认初始化,即所有基本类型的值都初始化为0或false;所有引用类型的值都初始化为null。使用静态工厂方法创建Bean实例时,还必须指定class属性,但此时class属性指定的不是Bean实例的实现类,而是一个静态工厂类。Spring通过这个属性知道使用哪个工厂类。创建一个Bean实例。另外,需要使用factory-method属性来指定静态工厂方法。Spring会调用静态工厂方法返回一个Bean实例。获取到指定的Bean实例后,Spring后续的处理步骤与正常创建Bean实例的方法完全一样。.如果静态工厂方法需要参数,请使用元素指定静态工厂方法的参数。调用实例工厂方法创建Bean实例工厂方法与静态工厂方法只有一个区别:调用静态工厂方法只需要工厂类,而调用实例工厂方法需要工厂实例。使用实例工厂方法时,配置bean实例的元素不需要class属性,配置实例工厂方法使用factory-bean指定工厂实例。使用实例工厂方法创建Bean的元素时,需要指定以下两个属性:factory-bean:该属性的值为工厂bean的idfactory-method:该属性指定实例工厂的工厂方法。如果调用实例工厂方法时需要传入参数,使用元素来确定参数值。协调范围不同步的Bean当单例范围的beans依赖于原型范围的beans时,将发生不同步。原因是在Spring容器初始化的时候,容器会预先初始化容器中所有的单例bean。单例Bean依赖于原型Bean,所以Spring会在初始化单例Bean之前创建原型Bean——然后创建单例Bean,然后将原型Bean注入到单例Bean中。解决不同步的方法有两种:放弃依赖注入:每次单例作用域的bean需要一个原型作用域的bean时,它会主动向容器请求一个新的bean实例,以确保每次注入原型bean实例timeisup-to-dateInstanceofusingmethodinjection:方法注入通常使用lookup方法注入,允许Spring容器重写容器中bean的抽象或具体方法,并返回查找其他方法的结果容器中的豆子。被查找的bean通常是非单例Bean。Spring通过使用JDK动态代理或者cglib库修改客户端的二进制代码来实现上述需求。推荐第二种方法,使用方法注入。使用lookup方法注入,大致需要以下两步:将调用者Bean的实现类定义为抽象类,定义抽象方法获取依赖的Bean2。在元素中添加子元素允许Spring为调用者Bean的实现类实现指定的抽象方法注释;Spring会使用运行时动态增强方法来实现元素指定的抽象方法,如果目标抽象类实现了,如果目标抽象类没有实现接口,Spring会使用cglib来实现抽象类并为它实现抽象方法。Spring4.0的spring-core-xxx.jar包中集成了cglib类库。两个后处理器:Spring提供了两个常用的后处理器:Bean后处理器:这个后处理器会对容器中的Bean进行后处理,另外对Bean进行强化;Containerpost-processor:这个后处理器会对IoC容器进行后处理,增强容器功能。Bean后处理器Bean后处理器是一种特殊的Bean。这个特殊的Bean不对外提供服务。它甚至不需要id属性。它主要负责对容器中的其他bean进行后处理,比如目标Bean生成代理等,这个Bean称为Bean后处理器。bean实例创建成功后,bean后处理器会进一步增强bean实例。Bean后处理器必须实现BeanPostProcessor接口,并且必须实现该接口的两个方法。1.ObjectpostProcessBeforeInitialization(Objectbean,Stringname)throwsBeansException:该方法第一个参数为系统要后处理的Bean实例,第二个参数为Bean的配置id2.ObjectpostProcessAfterinitialization(Objectbean,Stringname)throwsBeansException:该方法第一个参数为系统要进行后处理的Bean实例,第二个参数为Bean的配置id。一旦在容器中注册了bean后处理器,当容器中的每个bean被创建时,bean后处理器就会自动启动并自动工作。bean后处理器的两个方法的回调时机如下图所示。注意,如果使用BeanFactory作为Spring容器,必须手动注册Bean后处理器,程序必须获取Bean后处理器的实例,然后手动注册。BeanPostProcessorbp=(BeanPostProcessor)beanFactory.getBean("bp");beanFactory.addBeanPostProcessor(bp);Personp=(Person)beanFactory.getBean("person");容器后处理器Bean后处理器负责处理容器中的所有bean实例,而容器后处理器负责处理容器本身。容器后处理器必须实现BeanFactoryPostProcessor接口,并实现该接口的一个方法postProcessBeanFactory(ConfigurableListableBeanFactorybeanFactory)。该方法的方法体是Spring容器的处理。这个处理可以被定制并扩展到Spring容器中。当然,也可以不对Spring容器进行任何处理。与BeanPostProcessor类似,ApplicationContext可以自动检测容器中的容器后处理器,并自动注册容器后处理器。但是如果使用BeanFactory作为Spring容器,则必须手动调用容器后处理器来处理BeanFactory容器。Spring的“零配置”支持查找Bean类:Spring提供了如下注解来标记SpringBean@Component:标记一个普通的SpringBean类@Controller:标记一个控制器组件类@Service:标记一个业务逻辑组件类@Repository:标记一个DAO组件类,在Spring配置文件中做如下配置,指定自动扫描的包位于javax.annotation包下,有一个来自JavaEE规范的Annotation。Spring直接借用了这个Annotation,通过这个Annotation为目标Bean指定了一个collaboratorBean。使用@Resource与元素的ref属性具有相同的效果。@Resource不仅可以修改setter方法,还可以直接修改实例变量。如果使用@Resource修改实例变量,会更简单。这时候Spring会直接使用JavaEE规范的Field注入。这个时候连setter方法都不需要了。使用@PostConstruct和@PreDestroy自定义生命周期行为@PostConstruct和@PreDestroy也位于javax.annotation包下,也是JavaEE规范中的两个Annotation。Spring直接借用它们来定制Spring容器中bean的生命周期行为。它们用于装饰没有任何属性的方法。前者修饰的方法是Bean的初始化方法;后者修改的方法是Bean销毁前的方法。Spring4.0增强的自动装配和精确装配Spring提供了@Autowired注解来指定自动装配。@Autowired可以修改setter方法、普通方法、实例变量和构造函数。使用@Autowired注解setter方法时,默认采用byType自动装配策略。在这种策略下,往往有多个符合自动组装类型的候选Bean实例,此时可能会引发异常。为了实现准确的自动装配,Spring提供了@Qualifier注解。通过使用@Qualifier,允许使用Bean的id来执行自动装配。为什么Spring的AOP需要AOP?AOP(AspectOrientProgramming)即面向方面的编程。作为面向对象编程的补充,已经成为一种比较成熟的编程方法。事实上,AOP出现的时间并不长。AOP和OOP相辅相成。面向切面编程将程序运行过程分解为各个方面。AOP专门用来处理分布在系统中各个模块(不同方法)的交叉焦点问题。在JavaEE应用中,AOP经常被用来处理一些具有横切属性的系统级服务,比如事务管理、安全检查、Cache、对象池管理等,AOP已经成为一种非常普遍的解决方案。用AspectJ实现AOPAspectJ是一个基于Java的AOP框架,它提供了强大的AOP功能,许多其他AOP框架也借鉴或采用了其中的一些思想。它主要包括两部分:一部分定义了在AOP编程中如何表达和定义语法规范。通过这套语法规范,可以很方便地使用AOP来解决Java语言中的交叉焦点问题;另一部分是Tools部分,包括编译和调试工具等。AOP实现分为两类1.静态AOP实现:AOP框架在编译阶段对程序进行修改,即实现目标的增强类并生成一个静态AOP代理类,以AspectJ为代表2.动态AOP实现:AOP框架AOP代理是在运行阶段动态生成的,用于增强目标对象,以SpringAOP为代表。一般来说,静态AOP实现性能较好,但需要特殊的编译器。动态AOP实现是纯Java实现,所以不需要专门的编译器,但性能通常会稍差一些。AOP的基本概念是关于面向方面编程的一些术语。或者抛出异常。在SpringAOP中,连接点始终是方法调用;增强处理(Advice):AOP框架在特定入口点进行的增强处理。Processing有“around”、“before”、“after”等类型;切入点(Pointcut):可以插入以增强处理的连接点。简而言之,当一个连接点满足指定的要求时,就会对该连接点进行增强处理,该连接点将成为Spring的AOP支持的入口点;Spring中的AOP代理负责Spring的IoC容器的生成、管理,其依赖也由IoC容器管理。为了在应用中使用@AspectJ支持,Spring需要添加三个库:aspectjweaver.jaraspectjrt.jaraopalliance.jar,并在Spring配置文件中做如下配置:最后,如果您觉得本文对您有帮助,请点个赞。或者可以加入我的开发交流群:1025263163互相学习,我们会有专业的技术解答。如果您觉得这篇文章对您有用,请给我们的开源项目一个小星星:https://gitee。com/ZhongBangKe...非常感谢!JAVA学习手册:https://doc.crmeb.com技术交流论坛:https://q.crmeb.com