Spring使用指南
1. 容器:
BeanFactory是IOC容器的实际代表者,负责容纳和管理Bean;
2. 配置元数据
元数据有多种形式,如XML和annotation,其在Spring中代表同一个对象BeanDefinition;
3. 加载元数据
可通过多种方式加载元数据,如本地文件系统,ClassPath等;
4. Bean的定义
包括2部分:Bean标签自身的DTD或schema定义,Bean对象的定义;
Bean标签自身的DTD或schema定义:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd "
>
Bean对象的定义:
可以用XML或者注解的方式;
5. 多个Bean定义文件
两种方式:
1. 在初始化容器时提供多个Bean文件的位置或者一个通配符表达的位置;
2. 在一个Bean定义文件中通过<import resource="">来导入文件,注意import必须在bean之前;
6. Bean的别名
用<alias name="bean ID" alias="别名">
7. 内部类的Bean表示
其class属性值为:外部类全限定名$内部类名
8. Bean的实例化
1)构造器
为默认方法
<bean id="" class=""/>
2)静态工厂方法
<bean id="Bean实例Id" class="静态工厂类全限定名" factory-method="静态工厂产生实例的方法名"/>
3)实例工厂方法
<bean id="Bean实例Id" factory-bean="工厂实例Id" factory-method="工厂产生Bean实例的方法名"/>
4)容器
通过Spring容器的getBean(String Id)方法来获取实例;
9. 注入依赖
有2种:构造器注入和setter方法注入;
10. 依赖关系处理步骤:
根据定义Bean的配置创建并初始化BeanFactory实例,此时会验证Bean的配置,包括Bean引用的属性是否指向一个有效的Bean;
对于singleton类型和设为提前实例化的Bean,会与BeanFactory同时创建;
11. 依赖配置
1. 简单属性值的配置方式:
1):
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/mydb</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>masterkaoli</value>
</property>
</bean>
2):
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="username" value="root"/>
<property name="password" value="masterkaoli"/>
</bean>
3):属性值对的配置方式
<bean id="mappings" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties">
<value>
jdbc.driver.className=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb
</value>
</property>
</bean>
12. 延迟初始化Bean
1)在Bean定义中加入lazy-init="true"
2)在Beans定义中加入<beans default-lazy-init="true"></beans>来全局延迟初始化;
13. 自动装配autowire
1)自动装配启用:
在Beans中添加:<beans autowire="自动装配类型"></beans>
2)自动装配类型:
byName:根据名称自动装配,即属性名与Bean的ID相同且有set方法;
byType:根据类型装配,如果有多个匹配类型,则抛异常;
constructor:与byType相同,提供构造器参数;
autodetect:自动决定使用byType还是constructor;
3)自动装配优缺点:
优点:
减少配置数量,与Java代码同步更新;
缺点:
如装配不明确可能出现一些莫名BUG,对象之间的关联关系不再清晰;
4)Bean排除在自动装配之外
Bean添加autowire-cadidate=false
14. 单例对象的多例属性注入
采用Lookup的方法注入:
<bean id="command" class="fiona.apple.AsyncCommand" scope="prototype"/>
<bean id="commandManager" class="fiona.apple.CommandManager">
<lookup-method name="createCommand" bean="command"/>
</bean>
首先,方法必须是抽象的,如果有实现,动态生成的子类仍然会覆盖该方法;
其次,类和方法都不能是final的;
15. Bean的作用域(Scope)
1)配置Bean作用域
<bean id="command" class="fiona.apple.AsyncCommand" scope="作用域"/>
2)作用域类型:
singleton,prototype,request,session,global session;
3)使用request,session,global session作用域
1. 在Bean定义中加入<aop:scoped-proxy/>
2. servlet2.4及以后的版本,web.xml中加入:
<web-app>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
</web-app>
servlet2.3及之前的版本,web.xml加入:
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.<aop:scoped-proxy/>不能在singleton,prototype作用域的Bean定义中添加;
16. 生命周期回调
分为初始化回调和析构回调;
初始化回调:
1)实现InitializingBean接口
2)配置bean的inti-method="初始化回调方法名"并在该bean中实现该方法;
3)缺省初始化方法,配置beans的default-init-mehtod参数,则会调用所有bean的相应初始化方法;
析构回调:
1)实现DisposableBean接口
2)配置bean的destroy-method="初始化回调方法名"并在该bean中实现该方法;
3)缺省初始化方法,配置beans的default-destroy-mehtod参数,则会调用所有bean的相应初始化方法;
Bean初始化方法执行顺序:
@PostConstructor元注解->afterPropertiesSet()->inti-method,相同方法只执行一次
Bean析构方法执行顺序:
@PreDestroy注解的方法->destroy()->destroy-method
注意:生命周期的初始化回调方法是直接与原生Bean打交道,而非代理对象,故此时所有的AOP都不发生作用;
17. 利用MessageSource实现国际化以及消息参数化(适用于ApplicationContext)
1)配置消息Bean
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>format</value> //为资源文件列表
<value>exceptions</value>
<value>windows</value>
</list>
</property>
</bean>
2)使用方法:
调用MessageSource实例的getMessage()方法,可传入参数代替消息中的占位符;
根据local参数决定使用哪个参数文件;
18. 基于注解的配置(Annotation-based)
1)启用:
<Beans>配置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
</beans>
2)@AutoWired
@AutoWired可用于set方法,属性值,构造器方法上;当其用于属性值时,并不需要有对应的set方法;
默认采用byType方式,用@Qualifier时,则采用byName方式;
@Resource
与@AutoWired相同,但默认采用byName方式,有name和type属性,指定某个时,切换成对应的方式;
19. 组件扫描
1)启用组件扫描:
同样要在Beans中引入context的DTD文件以及命名空间
添加<context:component-scan base-package="org.example"/>
2)可扫描的组件标签
@Component,@Repository,@Service,@Controller
3)指定组件作用域
使用@Scope
4)指定Bean名
使用@Qualifier
20. Resource接口:
表示各种资源的抽象;
Resource种类:
UrlResource,ClassPathResource,FileSystemResource,ServletContextResource,InputStreamResource,ByteArrayResource;
21: ResourceLoader接口:
根据资源位置的字符串变量表示返回对应的资源对象;
资源位置的前缀,如classpath:,file:,http:隐式的指定了ResourceLoader对象以及返回的Resouce类型;
22. Resource作为属性来配置
如果程序中有Resource对象,则只要在配置中填写对应的资源位置,则spring在装置时会将资源位置自动转换为Resource对象;
如:<bean id="myBean" class="...">
<property name="template" value="some/resource/path/myTemplate.txt"/>
</bean>
24:classpath:与classpath*:前缀的区别:
1)二者都可以使用通配符来表示路径
2)二者均指定返回ClassPathResource对象
3)classpath:只返回符合要求的第一个对象,而classpath*则返回符合要求的所有Resource对象;
4)classpath*采用ClassLoader.getResource(),故依赖于不同应用服务器的ClassLoader实现,可能会有不同;
25. AOP的XML配置方式:
1)实现了AOP方法的bean类;
2)Beans中引入aop的DTD及命名空间;
3)添加如下配置
<bean id="testInterceptor" class="framework.util.SpringInterceptor"></bean>
<aop:config>
<aop:aspect id="aoptest" ref="testInterceptor">
<aop:pointcut id="cut" expression="execution(* framework.dao.*.*(..))" />
<aop:before pointcut-ref="cut" method="beforeMethod" />
<aop:after pointcut-ref="cut" method="afterMethod" />
<aop:after-returning method="returnMethod"
pointcut-ref="cut" />
<aop:after-throwing method="throwMethod"
pointcut-ref="cut" />
<aop:around method="doBasicProfiling" pointcut-ref="cut"/>
</aop:aspect>
</aop:config>
26. 通知类型:
前置通知,后置通知,异常通知,最终通知,环绕通知;
环绕通知与其它通知的区别:可控制何时调用目标方法
可控制返回对象
后置通知与最终通知的区别:后置通知在方法正常返回时执行
最终通知无论方法正常还是异常都会执行
各种通知都可以通过实现Spring自带接口来获得执行时的更多参数(如对象,方法等参数)
27. AOP的两种方式:
通过AspectJ即注释(annotation)、XMLSchema的方式;
AspectJ与XML的区别:
实现方式:AspectJ通过在通知类中加入匹配的注释来实现,需要在SPRING配置中加<aop:aspectj-autoproxy/>
XML则通过在XML中配置来实现,通知类中不需要加注释;
JDK支持:AspectJ需要JDK5+支持,XML不需要;
习惯:用户更习惯于XML;
28. JDK与Cglib代理
1. JDK采用JDK的动态代理,主要采用的是反射的方法在方法的前后添加AOP;
Cglib则采用的继承的方式,通过在子类方法中覆盖父方法来实现在父方法前后添加AOP;
2. Cglib不能实现对final对象及final和private方法的AOP,而JDK可以;
3. Spring中默认对象只要实现接口,就使用JDK;这样会导致用JDK代理产生的对象无法转为对象本身,产生CastException;
全局启用Cglib代理的方法:
<aop:config proxy-target-class=”true” />
如果是对@AspectJ提供支持,则使用<aop:scoped-proxy proxy-target-class=”true” />
29. 单元测试
Mock对象
org.springframework.mock.jndi包提供了JNDI的Mock对象;
org.springframework.mock.web包提供了Servlet API的Mock对象;
org.springframework.mock.web.portlet提供了Portlet API的Mock对象;
30. 事务:
1. 事务属性:
事务隔离,事务传播,事务超时,只读状态
2. 事务管理:
Spring对于不同的事务,实现了不同的事务管理器,如
对于JDBC是DataSourceTransactionManager,Hibernate是HibernateTransactionManager,全局事务则是JTATransactionManager;
3. 涉及事务处理的封装持久化API:
对于不同的事务,Spring用模板类封装了事务处理的过程,如JDBCTemplate,HibernateTemplate,JdoTemplate;
4. 事务的连接的封装类: 通过DataSourceUtils(JDBC),SessionFactoryUtils(Hibernate),PersistenceManagerFactoryUtils(JDO),确保了事务底层的Connection的一致性,进而保证了事务的一致性;
11. Dao层支持:
为各种DAO技术提供了Support类供扩展,简化了DAO层的处理工作;
JDBCDaoSupport: 需DataSource,提供JDBCTemplate;
HibernateDaoSupport:需SessionFactory,提供HibernateTemplate;
JdoDaoSupport: 需PersistenceManagerFactory,提供JdoTemplate;
JpaDaoSupport: 需EntityManagerFactory,提供JpaTemplate;
1. 容器:
BeanFactory是IOC容器的实际代表者,负责容纳和管理Bean;
2. 配置元数据
元数据有多种形式,如XML和annotation,其在Spring中代表同一个对象BeanDefinition;
3. 加载元数据
可通过多种方式加载元数据,如本地文件系统,ClassPath等;
4. Bean的定义
包括2部分:Bean标签自身的DTD或schema定义,Bean对象的定义;
Bean标签自身的DTD或schema定义:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd "
>
Bean对象的定义:
可以用XML或者注解的方式;
5. 多个Bean定义文件
两种方式:
1. 在初始化容器时提供多个Bean文件的位置或者一个通配符表达的位置;
2. 在一个Bean定义文件中通过<import resource="">来导入文件,注意import必须在bean之前;
6. Bean的别名
用<alias name="bean ID" alias="别名">
7. 内部类的Bean表示
其class属性值为:外部类全限定名$内部类名
8. Bean的实例化
1)构造器
为默认方法
<bean id="" class=""/>
2)静态工厂方法
<bean id="Bean实例Id" class="静态工厂类全限定名" factory-method="静态工厂产生实例的方法名"/>
3)实例工厂方法
<bean id="Bean实例Id" factory-bean="工厂实例Id" factory-method="工厂产生Bean实例的方法名"/>
4)容器
通过Spring容器的getBean(String Id)方法来获取实例;
9. 注入依赖
有2种:构造器注入和setter方法注入;
10. 依赖关系处理步骤:
根据定义Bean的配置创建并初始化BeanFactory实例,此时会验证Bean的配置,包括Bean引用的属性是否指向一个有效的Bean;
对于singleton类型和设为提前实例化的Bean,会与BeanFactory同时创建;
11. 依赖配置
1. 简单属性值的配置方式:
1):
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/mydb</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>masterkaoli</value>
</property>
</bean>
2):
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="username" value="root"/>
<property name="password" value="masterkaoli"/>
</bean>
3):属性值对的配置方式
<bean id="mappings" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties">
<value>
jdbc.driver.className=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb
</value>
</property>
</bean>
12. 延迟初始化Bean
1)在Bean定义中加入lazy-init="true"
2)在Beans定义中加入<beans default-lazy-init="true"></beans>来全局延迟初始化;
13. 自动装配autowire
1)自动装配启用:
在Beans中添加:<beans autowire="自动装配类型"></beans>
2)自动装配类型:
byName:根据名称自动装配,即属性名与Bean的ID相同且有set方法;
byType:根据类型装配,如果有多个匹配类型,则抛异常;
constructor:与byType相同,提供构造器参数;
autodetect:自动决定使用byType还是constructor;
3)自动装配优缺点:
优点:
减少配置数量,与Java代码同步更新;
缺点:
如装配不明确可能出现一些莫名BUG,对象之间的关联关系不再清晰;
4)Bean排除在自动装配之外
Bean添加autowire-cadidate=false
14. 单例对象的多例属性注入
采用Lookup的方法注入:
<bean id="command" class="fiona.apple.AsyncCommand" scope="prototype"/>
<bean id="commandManager" class="fiona.apple.CommandManager">
<lookup-method name="createCommand" bean="command"/>
</bean>
首先,方法必须是抽象的,如果有实现,动态生成的子类仍然会覆盖该方法;
其次,类和方法都不能是final的;
15. Bean的作用域(Scope)
1)配置Bean作用域
<bean id="command" class="fiona.apple.AsyncCommand" scope="作用域"/>
2)作用域类型:
singleton,prototype,request,session,global session;
3)使用request,session,global session作用域
1. 在Bean定义中加入<aop:scoped-proxy/>
2. servlet2.4及以后的版本,web.xml中加入:
<web-app>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
</web-app>
servlet2.3及之前的版本,web.xml加入:
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.<aop:scoped-proxy/>不能在singleton,prototype作用域的Bean定义中添加;
16. 生命周期回调
分为初始化回调和析构回调;
初始化回调:
1)实现InitializingBean接口
2)配置bean的inti-method="初始化回调方法名"并在该bean中实现该方法;
3)缺省初始化方法,配置beans的default-init-mehtod参数,则会调用所有bean的相应初始化方法;
析构回调:
1)实现DisposableBean接口
2)配置bean的destroy-method="初始化回调方法名"并在该bean中实现该方法;
3)缺省初始化方法,配置beans的default-destroy-mehtod参数,则会调用所有bean的相应初始化方法;
Bean初始化方法执行顺序:
@PostConstructor元注解->afterPropertiesSet()->inti-method,相同方法只执行一次
Bean析构方法执行顺序:
@PreDestroy注解的方法->destroy()->destroy-method
注意:生命周期的初始化回调方法是直接与原生Bean打交道,而非代理对象,故此时所有的AOP都不发生作用;
17. 利用MessageSource实现国际化以及消息参数化(适用于ApplicationContext)
1)配置消息Bean
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>format</value> //为资源文件列表
<value>exceptions</value>
<value>windows</value>
</list>
</property>
</bean>
2)使用方法:
调用MessageSource实例的getMessage()方法,可传入参数代替消息中的占位符;
根据local参数决定使用哪个参数文件;
18. 基于注解的配置(Annotation-based)
1)启用:
<Beans>配置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
</beans>
2)@AutoWired
@AutoWired可用于set方法,属性值,构造器方法上;当其用于属性值时,并不需要有对应的set方法;
默认采用byType方式,用@Qualifier时,则采用byName方式;
@Resource
与@AutoWired相同,但默认采用byName方式,有name和type属性,指定某个时,切换成对应的方式;
19. 组件扫描
1)启用组件扫描:
同样要在Beans中引入context的DTD文件以及命名空间
添加<context:component-scan base-package="org.example"/>
2)可扫描的组件标签
@Component,@Repository,@Service,@Controller
3)指定组件作用域
使用@Scope
4)指定Bean名
使用@Qualifier
20. Resource接口:
表示各种资源的抽象;
Resource种类:
UrlResource,ClassPathResource,FileSystemResource,ServletContextResource,InputStreamResource,ByteArrayResource;
21: ResourceLoader接口:
根据资源位置的字符串变量表示返回对应的资源对象;
资源位置的前缀,如classpath:,file:,http:隐式的指定了ResourceLoader对象以及返回的Resouce类型;
22. Resource作为属性来配置
如果程序中有Resource对象,则只要在配置中填写对应的资源位置,则spring在装置时会将资源位置自动转换为Resource对象;
如:<bean id="myBean" class="...">
<property name="template" value="some/resource/path/myTemplate.txt"/>
</bean>
24:classpath:与classpath*:前缀的区别:
1)二者都可以使用通配符来表示路径
2)二者均指定返回ClassPathResource对象
3)classpath:只返回符合要求的第一个对象,而classpath*则返回符合要求的所有Resource对象;
4)classpath*采用ClassLoader.getResource(),故依赖于不同应用服务器的ClassLoader实现,可能会有不同;
25. AOP的XML配置方式:
1)实现了AOP方法的bean类;
2)Beans中引入aop的DTD及命名空间;
3)添加如下配置
<bean id="testInterceptor" class="framework.util.SpringInterceptor"></bean>
<aop:config>
<aop:aspect id="aoptest" ref="testInterceptor">
<aop:pointcut id="cut" expression="execution(* framework.dao.*.*(..))" />
<aop:before pointcut-ref="cut" method="beforeMethod" />
<aop:after pointcut-ref="cut" method="afterMethod" />
<aop:after-returning method="returnMethod"
pointcut-ref="cut" />
<aop:after-throwing method="throwMethod"
pointcut-ref="cut" />
<aop:around method="doBasicProfiling" pointcut-ref="cut"/>
</aop:aspect>
</aop:config>
26. 通知类型:
前置通知,后置通知,异常通知,最终通知,环绕通知;
环绕通知与其它通知的区别:可控制何时调用目标方法
可控制返回对象
后置通知与最终通知的区别:后置通知在方法正常返回时执行
最终通知无论方法正常还是异常都会执行
各种通知都可以通过实现Spring自带接口来获得执行时的更多参数(如对象,方法等参数)
27. AOP的两种方式:
通过AspectJ即注释(annotation)、XMLSchema的方式;
AspectJ与XML的区别:
实现方式:AspectJ通过在通知类中加入匹配的注释来实现,需要在SPRING配置中加<aop:aspectj-autoproxy/>
XML则通过在XML中配置来实现,通知类中不需要加注释;
JDK支持:AspectJ需要JDK5+支持,XML不需要;
习惯:用户更习惯于XML;
28. JDK与Cglib代理
1. JDK采用JDK的动态代理,主要采用的是反射的方法在方法的前后添加AOP;
Cglib则采用的继承的方式,通过在子类方法中覆盖父方法来实现在父方法前后添加AOP;
2. Cglib不能实现对final对象及final和private方法的AOP,而JDK可以;
3. Spring中默认对象只要实现接口,就使用JDK;这样会导致用JDK代理产生的对象无法转为对象本身,产生CastException;
全局启用Cglib代理的方法:
<aop:config proxy-target-class=”true” />
如果是对@AspectJ提供支持,则使用<aop:scoped-proxy proxy-target-class=”true” />
29. 单元测试
Mock对象
org.springframework.mock.jndi包提供了JNDI的Mock对象;
org.springframework.mock.web包提供了Servlet API的Mock对象;
org.springframework.mock.web.portlet提供了Portlet API的Mock对象;
30. 事务:
1. 事务属性:
事务隔离,事务传播,事务超时,只读状态
2. 事务管理:
Spring对于不同的事务,实现了不同的事务管理器,如
对于JDBC是DataSourceTransactionManager,Hibernate是HibernateTransactionManager,全局事务则是JTATransactionManager;
3. 涉及事务处理的封装持久化API:
对于不同的事务,Spring用模板类封装了事务处理的过程,如JDBCTemplate,HibernateTemplate,JdoTemplate;
4. 事务的连接的封装类: 通过DataSourceUtils(JDBC),SessionFactoryUtils(Hibernate),PersistenceManagerFactoryUtils(JDO),确保了事务底层的Connection的一致性,进而保证了事务的一致性;
11. Dao层支持:
为各种DAO技术提供了Support类供扩展,简化了DAO层的处理工作;
JDBCDaoSupport: 需DataSource,提供JDBCTemplate;
HibernateDaoSupport:需SessionFactory,提供HibernateTemplate;
JdoDaoSupport: 需PersistenceManagerFactory,提供JdoTemplate;
JpaDaoSupport: 需EntityManagerFactory,提供JpaTemplate;