发表于: 2018-04-04 23:56:19

1 687


今天完成的事情: 

任务1.19

学习Spring,配置Spring和Junit 

之前搭建Spring环境的时候简单的看了一下spring知识,现在再详细复习一下。

分为几个知识点吧:IoC容器,依赖注入,AOP,JDBC框架,事务管理,Spring web MVC框架。JDBC框架主要就是看过的JdbcTemplate那些。

Spring IoC容器:

IoC的意思是控制反转(Inversion of Control),是一种设计思想,它意味着将设计好的对象交给容器控制,而不是直接在你的对象内部控制(如使用new创建等)。

Spring运行后会根据xml配置信息和Java中的注解,生成相应的对象,并将这些对象放在应用的上下文环境中,等待着被程序使用。

所以Spring就好像一个装着bean对象的容器一样,你不再需要手动在代码中创建依赖的对象了,等着Spring容器帮你注入就好,由主动变为被动了,就是控制反转(IoC)。

那Spring将这些bean对象存在哪里了?Spring提供了两种不同类型的容器:BeanFactory容器和ApplicationContext容器。

BeanFactory容器是最简单的容器,提供了基本的依赖注入功能,可以用于轻量级的程序中,如移动设备或基于applet的应用程序。

ApplicationContext容器包括BeanFactory容器的所有功能,并添加了更多的企业特定的功能,一般建议使用ApplicationContext容器

ApplicationContext接口最常使用的三个实现类

FileSystemXmlApplicationContext:该容器从XML文件中加载定义的bean,路径是文件系统。

ClassPathXmlApplicationContext:该容器从XML文件中加载定义的bean,路径是类路径。

WebXmlApplicationContext:该容器在Web应用程序范围内加载在XML文件中定义的bean。

例子:

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //加载bean
AboutJdbcTemplate about = (AboutJdbcTemplate) context.getBean("AboutJdbcTemplate"); //获取bean

这些被容器加载的Bean有三种定义方式:基于XML配置,基于注解配置,基于Java代码配置。

XML方式:

<bean id="student" class="xx.xx.Student"></bean>

Bean的五个作用域:singleton,prototype,request,session,global-session。后三个在web应用中可用。

singleton:单例模式,容器中只有一个实例对象。

prototype:每次使用都创建新的实例对象。

默认作用域为singleton,使用scope参数配置:

<bean id="student" class="xx.xx.Student" scope="prototype"></bean>

Bean的初始化和销毁方法:init-method、destroy-method

<bean id="student" class="xx.xx.Student" init-method="init" ></bean>

init-method参数指定的方法在实例化bean时立即调用(调用完构造函数后),destroy-method指定的方法在bean被移除容器后调用。

另外还有实现Spring提供的特定接口的方式来定义初始化和销毁方法,但不建议,因为方法命名是固定的,不如XML配置灵活。

如果很多Bean都有相同的初始化和销毁方法,可以不用在每个Bean里都定义,而是在beans元素中使用默认配置,如下:

<beans xmlns="..." ...default-init-method="init">

    <bean>...</bean>

</beans>

Bean的后置处理器:BeanPostProcessor

如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中。

BeanPostProcessor的实现类要实现两个方法,分别在Bean初始化的前后执行,这里的之前是指构造函数之后、自定义的初始化方法之前(如上面的init-method标签定义),之后指的是自定义初始化方法之后。具体代码就不写了,用到再说。

Bean的定义继承:

与Java继承无关,但概念是一样的。继承的是bean的配置信息,如属性等。例:

<bean id="student" class="xx.xx.Student">

    <property name="name" value="江吉仪" />

    <property name="qq" value="1234567" />

</bean>

<bean id="god" class="xx.xx.God" parent="student">

    <property name="name" value="GOD" />

    <property name="age" value="9999999" />

</bean>

上面例子中,id为god的Bean继承了student的name和qq两个属性,并重写了name属性,又增加了一个新属性age。

bean定义模板:上面例子中被继承的是一个可被实例化的bean,若想定义一个只用来给其它子定义继承用的模板bean,则如下:

<bean id="beanTemplate" abstract="true">

    <property name="name" value="江吉仪" />

    <property name="qq" value="1234567" />

</bean>

该定义不能被实例化,因为没有class属性,而且被abstract参数标记为抽象的,仅仅作为定义模板来使用。

以上是和Spring IoC容器有关的知识总结。

Spring 依赖注入:

有关控制反转和依赖注入的概念,可参考文章:https://blog.csdn.net/qq_22654611/article/details/52606960/

依赖注入的方式:基于构造方法的注入,基于setter方法的注入。

基于构造方法的注入,构造方法需要带有参数,当调用构造方法时则通过参数进行注入,XML配置如下:

<bean id="student" class="xx.xx.Student">

    <constructor-arg ref="xxClass" />

</bean>

若构造方法有多个参数,为防止歧义,bean中定义构造参数时的顺序需要与构造方法中参数顺序一致。

若参数类型不同,则可以使用类型(type)属性显式指定参数类型进行匹配:

<bean id="student" class="xx.xx.Student">

    <constructor-arg type="java.lang.String" value="江吉仪"/>

    <constructor-arg type="int" value="18" />

</bean>

或者使用序号的方式(推荐):

<bean id="student" class="xx.xx.Student">

    <constructor-arg index="0" value="江吉仪"/>

    <constructor-arg index="1" value="18" />

</bean>

基于setter方法的注入,之前日报代码常用的方式,如:

<bean id="student" class="xx.xx.Student">

    <property name="xx" ref="xxClass" />

</bean>

Student的xx属性需要有setter方法。另一种格式是使用p-namespace,如下:

<bean id="student" class="xx.xx.Student" p:name="god" p:xx-ref="xxClass">

</bean>

多个参数时使用p标签可以少写点代码,不过要加上p的命名空间:xmlns:p="http://www.springframework.org/schema/p"

注入内部Bean,即在<bean>标签内使用<bean>标签,可以注入内部类。

注入集合:可以使用<list><set><map><props>标签,例如:

<bean id="student" class="xx.xx.Student">

    <property name="xxList">

        <list>

            <value>Rose</value>

            <value>Jack</value>

        </list>

    </property>

</bean>

其它三种标签的使用方法,map下使用<entry key="xx" value="xx">格式,props下使用<prop key="xx">xx</prop>格式,set与list相同。

注入引用的格式:

<list>

    <ref bean="xxClass"/>

    <ref bean="yyClass"/>

</list>

其它两种标签:map下使用<entry key="xx" value-ref="xx">格式,set与list相同。

注入NULL<property name="xx"><null/></property>

以上的依赖注入都是通过XML配置的<property>元素或者<constructor-arg>元素等,若不使用这些元素标签,还可以用自动装配的方式。

自动装配(autowire)的方式:byName,byType,by构造函数

byName方式:

<bean id="student" class="xx.xx.Student" autowire="byName">

</bean>

若Student类有某属性,并且XML配置中有id为该属性名字的bean,则会注入。

byType方式:

<bean id="student" class="xx.xx.Student" autowire="byType">

</bean>

Student类有某属性,并且XML配置中有class为该属性类型的bean,则会注入。若有多个id不同class相同的bean,则注入失败。

by构造函数方式:

<bean id="student" class="xx.xx.Student" autowire="constructor">

</bean>

通过构造函数的参数注入,XML配置中需要有id与该参数的类型相匹配的bean,才能注入。

以上依赖注入的方式,不管是普通方式还是自动装备,都要在XML文件里配置,下面使用注解方式配置。

使用注解需要在Spring中加上配置:<context:annotation-config/>

注解:@Required,@Autowired,@Qualifier

@Required:在setter方法上使用。一般setter注入即使没有执行注入也不会报错,只是属性值为空,用到时才可能报错,使用该注解则必须注入,否则报错。

@Autowired:可以用在setter方法上(byType)、属性上、构造方法上。默认也是必须的,可以加参数改变默认情况:@Autowired(required=false)

@Qualifier:合格者。当有多个相同类型的bean,且属性是按类型注入(byType)时,可以结合@Autowired@Qualifier指定真正需要的bean。

JSR-250注解:@PostConstruct 、 @PreDestroy和@Resource

前两个注解是自定义初始化和销毁方法,与之前的init=method标签类似。

@Resource,可以使用在setter方法和属性字段上,按byName方式注入。

@Configuration、@Bean、@Import注解,用于使用Java代码来配置Spring Bean

由于依赖注入关系不明确等原因,开发中貌似很少使用自动装配以及@Autowired等Spring特有的注解。

Spring中的事件处理及自定义事件、AOP编程、事务处理、Spring MVC大概看了遍,等用到时再总结。

任务1.19前一半学习Spring先到这,继续后一半配置Spring和Junit。

Spring之前已经搭建好环境,只需要把Junit集成进来。

任务1.20

编写单元测试代码。

测试类:

任务1.21

查看日志,并转成Debug模式,练习调试,学会查看单步执行时的变量值。


Debug模式之前经常用,F6单步执行,F5进入方法,F7跳出方法。还没有整合日志插件,就先看控制台日志吧。                      

明天计划的事情:    

完成任务1.22-1.24

熟悉linux操作

遇到的问题:    

在Spring中进行Junit4测试时,有些编译错误。原来是导入的Junit版本太低4.3,SpringJunit4ClassRunner类和Rule类都用不了。换成4.10版本,不报编译错误了,但是运行后报错,提示版本过低,需要4.12版本。可能是我的Spring版本太高了4.3.9,不兼容了。然后下载了4.12的版本,发现又报错说找不到某个类,百度了下原来4.12版本中减少了包,又下载了hamcrest-core-1.3.jar包导进来才能正常运行。         
收获:

总结了一下Spring的知识,主要是依赖注入的不同方式和方法,都写在了上面。

了解了在Spring的环境下使用Junit4进行单元测试的方法。



返回列表 返回列表
评论

    分享到