欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring-In-Action第一二章笔记

程序员文章站 2022-03-31 21:44:40
...

第一部分:Spring核心

    一.    简述Spring

           Spring作为一个轻量级的企业级开发框架,他的出现终结了重量级框架的统治(如EJB,applet)。尽管EJB在Spring的出现后紧追不舍,也推出类似Spring核心的功能,但Spring也没有停止他的脚步,他开始涉足于移动开发、社交API集成、NoSql数据库、云计算以及大数据领域。

            重量级框架的开发一般是强迫你继承他们的类或者接口,导致自己的类与框架绑死。此为侵入性编程(如Struts)。

            Spring的出现简化了JAVA开发,他主要有以下四点关键策略:

            1.    基于POJO的轻量级和最小侵入性编程

            2.    通过依赖注入和面向接口编程实现松耦合

            3.    基于切面和惯例进行声明式编程

            4.    通过切面和模板减少样式代码

  二、Spring核心功能介绍

            Spring为企业级开发提供了很多功能,但他的底层都依赖于两个核心特性:DI(依赖注入)和AOP(面向切面编程)

            DI:任何一个有实际意义的应用都会由两个或者更多的类组成,这些类之间的相互协作来完成特定的业务逻辑。按照传统的做法是每个类各自管理依赖于他的类(引用),但是这样会导致高度耦合和难以测试的代码。耦合具有两面性,一方面是紧耦合的代码难以复用、测试和理解,并且典型的表现形式是“打地鼠”式的BUG,另一方面,一定程序的耦合又是必须的。

            通过DI,对象的依赖关系将由系统中负责协调各对象的第三方组件在创建对象的时候进行设定,对象无需自动创建或管理他们之间的依赖关系。

Spring-In-Action第一二章笔记

            Spring通过应用上下文(Application context)装载创建bean对象并把他们组装起来。

            AOP:允许把遍布应用程序各处的功能分离出来形成可重用的组件。在实际编程过程中,我们写的代码不光需要考虑完成编程某一个类的某项具体功能,还要考虑别的职责(日志处理,事务管理这些融入业务的组件)。这样一来就会导致一个类会处理大多相同的任务,假使抽取出一个工具类,但是调用的代码还是会出现在各个模块中。这些组件都是与业务无关的,这些东西会使得代码变的混乱。

             而我们可以把AOP想象成依附在组件上的外壳。他们以声明的方式灵活地存在于系统中,核心功能不会知道它们的存在 

Spring-In-Action第一二章笔记

  三、Spring其他功能       

       1.   使用模板消除板式代码

        在日常编程中,不乏有很多重复的代码(如JDBC操作),在一个传统的JDBC操作中,如对一个对象的增删改查方法,他们除了所调用的SQL语句不同,其它的都大致相同。故没有必要去每次都把同样的事情操作写在代码中,造成了代码的冗余。Spring提供了jdbc模板来消除了板式代码。

        2.    应用上下文

        Spring提供了多种渠道来获取他的应用上下文。具体的你自己去百度。

        其中本书还提到了许多Spring的功能,还有Spring新版本的特性,在此不一一叙述,也没细看,先马起来。


第二章:装配Bean

        Spring装配Bean有三种方案:

        1.    在XML中进行显式配置

        2.    在Java中进行显式配置

        3.    隐式的Bean发现机制和自动装配

        作者提出的建议是尽可能的使用自动装配,再次是类型安全且强大的JAVA显示配置,最后 推荐XML配置。

        一、自动装配Bean

        要装配的类使用@ComPonent注解,这个注解表明这是一个组件类,并且告诉Spring要为这个类创建Bean。这时还要开启注解扫描功能,分为两种方法:

        1.    写一个配置类,这个类不用有任何方法,他的职责就是自动扫描与配置类相同的包下的所有实现Component注解的类并装配,这个类需要使用@Configuration和@ComponentScan来配置自动扫描。有些情况需要多个基本包,那么只需给@ComponentScan的basePackages传递一个字符数组即可,或者给basePackageClasses传递一个Class数组

    其中有一段不是很能理解,在此给出目前自己的一知半解:给要装配的类统一实现标记接口,在basePackageClasses中传递标记接口是重构代码的实现。

@Configuration
@ComponentScan
public class CDPlayerConfig {
}

        2.    使用XML配置注解扫描。<context:component-scan base-package="基本包名"/>

        自动装配Bean的id如果不给定会使用默认id,其规则是类名首字母小写

        当然实际编程中类的引用关系会很复杂,这里就涉及到了自动装配。它的实现方法有两种,均使用@Autowired注解

               (1)使用有参构造器传入

@Component
public class CDPlayer {
	private CompactDisc cd;
	@Autowired
	public CDPlayer(CompactDisc cd){
		this.cd = cd;
	}
}

               (2)使用Setter方法传入

@Component
public class CDPlayer {
	private CompactDisc cd;
	@Autowired
	public void setCd(CompactDisc cd) {
		this.cd = cd;
	}
}

        这里@Autowired不仅仅适用于此两种方法上,在自己编写的方法也可以正确使用。但是如果自己写的方法并没有成功注入属性,那么Spring会抛出一个异常,设置@Autowired(required=false)会避免异常的抛出,但在使用对象时会抛空指针异常。

    二、通过JAVA代码装配Bean

          尽管推荐自动装配,但有情况下自动装配是行不通的,例如我们要装配的是第三方的类库。javaConfig比XML配置更强大,类型安全并且重构友好。因为他可以说基本就是JAVA代码,但他与JAVA代码又不尽相同,在概念上,他与业务逻辑代码不同,他不包括任何业务逻辑,他也不应该侵入到业务逻辑包中,故通常把它单独放出一个包,使他与业务逻辑包分离。

        1.    声明简单的Bean我们在JavaConfig类中添加如下方法来自动为其返回对象,在有特殊需要时这种方法很灵活

@Configuration
public class CDPlayerConfig {
	@Bean
	public CompactDisc sgtPeppers(){
	    return new SgtPeppers();
	}
}

        2.    借助JavaConfig实现注入,而这里又可以分两种方法

        (1)有参构造器方式注入

@Configuration
public class CDPlayerConfig {
	@Bean
	public CompactDisc sgtPeppers(){
		return new SgtPeppers();
	}
	@Bean
	public CDPlayer cdPlayer(){
		return new CDPlayer(sgtPeppers());
	}
}

           方法体只需在参数方法调用sgtPeppers方法来返回一个CompactDisc对象即可。

           这种方法看起来是每调用一次会返回一个新的对象,这里无需担心,Spring已经为我们做好了准备,我们都知道Spring的Bean是单例对象,它的调用并不同于平常的调用,Spring会自动拦截调用请求,确保单例。

            上述实现注入方法较为难理解,这里作者提供了一种更为好理解的方式。这里Spring会自动寻找CompactDisc对象为我们自己作为参数传递进去,实现自动注入。

@Configuration
public class CDPlayerConfig {
	@Bean
	public CompactDisc sgtPeppers(){
		return new SgtPeppers();
	}
	@Bean
	public CDPlayer cdPlayer(CompactDisc compactDisc){
		return new CDPlayer(compactDisc);
	}
}

            (2)Setter方法注入

@Configuration
public class CDPlayerConfig {
	@Bean
	public CompactDisc sgtPeppers(){
		return new SgtPeppers();
	}
	@Bean
	public CDPlayer cdPlayer(CompactDisc compactDisc){
		CDPlayer player = new CDPlayer();
		player.setCd(compactDisc);
		return player;
	}
}

    三、通过XML装配Bean

<bean id = "knight" class="di.and.aop.BraveKnight"/>

        在属性注入时有两种方式,依旧是有参构造和Setter方法注入

        有参构造,如果要注入的属性是简本数据类型(包括String),则使用constructor-value标签注入

<bean id = "knight" class="di.and.aop.BraveKnight">
	<constructor-arg ref="quest"></constructor-arg>
</bean>

           Setter注入,name为要注入的属性名,ref指要注入的Bean对象引用

<bean id = "knight" class="di.and.aop.BraveKnight">
	<property name="quest" ref="quest" ></property>
</bean>

        其中不管哪种注入方式,都会有面临注入集合的情况,这种情况需要在property里引用<list><value><value>...</list>或者<set>标签引入即可


四、几种装配方式混合使用

        Spring允许程序员*选取装配方式,而且支持混合装配。那么就会涉及到几种装配方式之间的协作,如何引用问题

        1.    在JavaConfig中引用XML配置和JavaConfig的拆分

              在实际的配置类中,可能配置项会非常多,造成重构时分离代码的需要,而分离就意思着引用。这里例如有两个配置类,与其让他们互相引用不如抽出一个更高级的配置类,让高级配置类来引用其两个低级配置类。这里引用使用@Import注解,里面需要的参数为Class对象。那么在JavaConfig中引用XML配置是如何操作的呢?使用@ImportResource注解,参数接收XML的路径,即可实现引用。

        2.    在XML中引用JavaConfig配置

        这里XML的<import>标签并不能很好的完成任务,这个标签只能引用同类XML文件,而不能引用类。这里我们应该使用一个我们熟知的<bean>标签来引用JavaConfig配置类来完成组合任务

        重要.    拆分Spring装配

        不管使用如何混合装配Bean,通常都应该有一个根配置。因Spring的Bean对象在实际项目中会很多很多,根配置便于管理也更好理解。


五、总结一下

        在使用Spring中装配方式推荐使用自动装配,这样会避免维护的成本。其次选用JavaConfig配置,这种配置方式更强大、灵活、安全并且易于重构。最后选用XML配置,这种配置方式是在Spring一开始就存在的,所以老项目中会很常见,也应该会用。

相关标签: b