Spring3的IoC与Spring2类似,只不过在表现形式上会有些许不同,下面就详细讲讲在Spring3中支持的IoC表示方式
第一种:基于XML配置
在Spring1.0的时候,使用DTD格式,Spirng2.0以后使用Schema格式,从而使不同配置类型有了自己的命名空间,简化了配置工作。
装配一个Bean
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> 6 7 8 <bean id="car" class="com.baobaotao.simple.Car"/> 9 <bean id="boss" class="com.baobaotao.simple.Boss" /> 10 </beans>
每一个Bean都需要指定唯一的一个id,id名称需要符合XML对id的命名规范。
如果希望对Bean的名称定义使用一些特殊字符,可以使用name属性代替id熟悉,一个Bean可以对应多个name属性值,值之间使用","分割即可
不同的Bean允许使用相同的name值,但是这就发生了覆盖,所以尽量使用id,因为一旦有重,就会被检测到。
如果id与name都没有指定,那么这个Bean的全限定类名就是默认的Bean的名称。
如果多个相同class值的Bean同时存在,如何获取呢? getBean("className"),getBean("className#1")getBean("className#2")
依赖注入
1 <bean id="car" class="com.baobaotao.ditype.Car"> 2 <property name="maxSpeed" value="200"/> 3 <property name="brand" value="红旗CA72"/> 4 <property name="price" value="20000.00"/> 5 </bean>
上述代码属于属性注入,每一个被注入的属性都需要提供对应的setter方法
除了属性注入外,还有构造函数注入,工厂方法注入,不常用,不再累述
支持级联属性的注入
集合类型的注入(使用util命名空间可以大大简化配置)
p命名空间的使用
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="car" class="com.baobaotao.ditype.Car" p:brand="红旗CA72" p:maxSpeed="200" p:price="20000.00" /> </beans>
自动装配
每个Bean元素都有一个autowire属性可以指定自动装配的类型
byName
byType
contructor
autodetect
自动装配虽然简化了配置,但是使得Bean之间的关系很不清晰,实际开发中很少用
Bean之间的关系、
继承:父类增加abstract="true"属性,子类通过parent属性设置父类。父类也可以不指定abstract属性,这样就会被Sping实例化
依赖:如果一个Bean依赖与另一个Bean,要们在书写配置信息的时候通过位置先后顺序,要么使用depends-on属性指定依赖的实例。这样就能够保证依赖关系的正确
第二种:基于注解的配置
不管是使用XML还是注解,它们都是表达Bean定义的载体,其实质都是为Spring提供Bean的定义信息。
XML分离了Bean定义信息与Bean实现类
注解则是在定义Bean的时候就将定义信息通过注解进行了说明
那么如何使用呢?思路就是两条,第一,在Spring配置文件中打开注解器,第二,为需要注解的Bean增加注解信息
<?xml version="1.0" encoding="UTF-8"?> <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" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"> <!--打开自动扫描--> <context:component-scan base-package="com.baobaotao.dao"/> <context:component-scan base-package="com.baobaotao.service"/> ...... </beans>
如上,就打开了注解器,将指定包下的类全部纳入了Spring管理器,当然,这些能够被纳入Spring容器的类需要经过一些注解的处理
package com.baobaotao.dao; import com.baobaotao.domain.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.stereotype.Component; import org.springframework.stereotype.Repository; import java.sql.ResultSet; import java.sql.SQLException; /** * Created by sherry on 000028/6/28 0:53. */ @Component("userDao") public class UserDao { ... }
@Controller 对控制器进行注解(Action等)
@Service 对Service进行注解
@Repository 对Dao进行注解
@Component 对其他需要纳入Spring容器的Bean进行注解
关于 <context:component-scan base-package="com.baobaotao.dao"/>
默认会扫描该包及其子包下的所有类
<context:component-scan base-package="com.baobaotao.dao" resource-pattern="anno/*.class"/>
扫描基包下指定子包下的所有类
如果需要实现更复杂的过滤规则,可以通过<context:component-scan>的过滤子元素实现
自动装配Bean
所有自动装配Bean,就是Bean通过注解自己去Spring容器中获取所依赖的对象
使用@Resource和@Autowired注解
默认@Autowird按照类型装配
@Autowired @Qualifier("jdbcTemplate") private JdbcTemplate jdbcTemplate;
Qualifier可以指定装配名称 第三种:基于Java类的配置一个Java配置类就相当于一个Spring配置文件普通的POJO只要标注了@Configuration注解,就可以为Spring提供Bean的定义信息了。
@Configuration注解本身已经实现了@Component
package com.baobaotao.conf; import com.baobaotao.dao.LoginLogDao; import com.baobaotao.dao.UserDao; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Created by sherry on 15-6-28. */ @Configuration public class DaoConf { @Bean public UserDao userDao(){ return new UserDao(); } @Bean public LoginLogDao loginLogDao(){ return new LoginLogDao(); } }
package com.baobaotao.conf; import com.baobaotao.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Created by sherry on 15-6-28. */ @Configuration public class ServiceConf { @Autowired/*daoConf 本身也能够被注入到其他Java配置配中 相当于XML 中的import*/ private DaoConf daoConf; @Bean public UserService userService(){ return new UserService(); } }
如何启动通过Java类配置的Spring容器呢?
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConf.class)
LoginService loginService = ctx.getBean(LoginService.class)
或者
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(DaoConf.class)
ctx.register(ServiceConfig.class)
ctx.refresh()
相当于读取多个XML配置文件
如果不想引入多个Java配置类,那么可以在Java配置类中使用 @Import(DaoConf.class) 注解,这样就只要进入一个即可,相当于XML中使用import,然后读取配置文件的时候只要读取一个总配置文件就行了
三种Bean配置方式的使用场景
个人觉的,一个比较好的方式是对于对于第三方jar包中的类,使用XML进行配置,自己的类,使用注解的方式配置。
XML中仅包含主题设置与第三方类的配置