Spring框架之IOC容器
1、怎样理解Spring的IOC容器:
IOC容器主要是对java中我们称之为Bean的程序主体进行初始化、装配以及管理。BeanFactory是IOC容器的核心接口。他的职责是实例化、定位、配置应用程序中的对象以及建立这些对象间的依赖。ApplicationContext接口是对BeanFactory的扩展,除了上述功能,他还对企业引用提供了许多基础支持,比如:事务处理和AOP。所以配置IOC容器ApplicationContext接口作为首选。
(1)在web.xml中利用ApplicationContext实例化IOC容器:
<!-- Spring ApplicationContext配置文件的路径,可使用通配符,多个路径用,号分隔,此参数用于后面的Spring Context Loader --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:/applicationContext.xml classpath*:/applicationContext-gather.xml </param-value> </context-param> <!--Spring的ApplicationContext 载入 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
ApplicationContext能以声明的方式创建,如ContextLoader,而ContextLoader有两种实现机制:ContextLoaderListener和ContextLoaderServlet,所以上述配置主要是通过ContextLoaderListener进行加载ApplicationContext.而监听器首先检查contextConfigLocation参数,如果参数不存在,他默认使用/WEB-INF/applicationContext.xml作为默认值。
(2)通过上述配置,我们就可以在applicationContext.xml文件中进行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:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" 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/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <description>导入ShowCase中的applicationContext文件列表</description> <import resource="security/applicationContext-security.xml" /> <!-- 生成抓取任务 --> <bean id="crawlTaskClass" class="com.gather.web.gather.bus.timertask.TaskTimerTask"/> <bean id="crawlTask" class="org.springframework.scheduling.timer.ScheduledTimerTask"> <property name="delay" value="0" /><!-- 单位为毫秒 --> <property name="period" value="20000" /> <property name="timerTask" ref="crawlTaskClass" /> </bean> <!-- 爬虫状态报告 --> <bean id="reportTaskClass" class="com.gather.web.gather.bus.timertask.ReportTimerTask"/> <bean id="reportTask" class="org.springframework.scheduling.timer.ScheduledTimerTask"> <property name="delay" value="20000" /><!-- 单位为毫秒 --> <property name="period" value="5000" /> <property name="timerTask" ref="reportTaskClass" /> </bean> <!-- 爬虫领取任务 --> <bean id="robotTaskClass" class="com.gather.web.gather.bus.timertask.RobotTimerTask"/> <bean id="robotTask" class="org.springframework.scheduling.timer.ScheduledTimerTask"> <property name="delay" value="10000" /><!-- 单位为毫秒 --> <property name="period" value="20000" /> <property name="timerTask" ref="robotTaskClass" /> </bean> <bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean"> <property name="scheduledTimerTasks"> <list> <ref local="crawlTask" /> <!-- <ref local="reportTask" /> <ref local="robotTask" /> --> </list> </property> </bean> </beans>
这里了解一下xml配置元数据的结构:
我们通过<import/>元素从另一个或多个文件加载bean的定义,以便加载多个XML文件生成一个ApplicationContext实例,但是<import/>元素必须在<bean/>定义之前完成bean的导入。
<beans> <import resource="services.xml"/> <import resource="resource/messageSource.xml"/> <import resource="/resource/themeSource.xml"/> <bean id="bean1" class=""/> </beans>
import中的元素都采用的是相对路径,services.xml一定要与导入文件放到同一目录下,而messageSource.xml和themeSource.xml的文件文职必须放到导入文件所在目录下的resource目录下,开头的“/”可以忽略。
在配置的bean中,有很多<beanid="bean1"class=""/>这样的配置,这是通过构造器来实例化bean对象,而我们所说的依赖是建联对象之间的联系。下面我们就了解一下依赖注入:
依赖注入主要分为“构造器注入”和“Setter注入”:对于构造器注入,会使得程序显得臃肿,笨拙,所以我们常用setter注入(主要通过property属性)方式:
第一种:直接变量的注入(基本类型、String类型等)
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <!-- Connection Info --> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean>
另一种写法是
<property name="password"> <value>${jdbc.password}</value> </property>
这样就通过这种注入的方式为BasicDataSource的password属性进行了赋值,就可以通过BasicDataSource的getPassword方法获取。
第二种是注入对象:
<bean id="singleDirectConnection" class="cn.nsl.web.util.SingleDirectConnection"> </bean> <bean id="SqlExecute" class="cn.nsl.web.util.SqlExecute"> <property name="singleDirectConnection" ref="singleDirectConnection" /> </bean>
这种方式,使得在cn.nsl.web.util.SqlExecute类中直接声明一个privateSingleDirectConnectionsingleDirectConnection;就可以通过singleDirectConnection对象调用类cn.nsl.web.util.SingleDirectConnection的任何方法。
第三种是一个特例:内部bean的注入:不用ref,而是用bean代替
<bean id="outer" class=""> <property name="target"> <bean class="com.example.Person"> <!--inner bean --> <property name="age" value="25"/> </bean> </property> </bean>
第四种是集合:可以通过<list/>、<set/>、<map/>定义List、Set、Map等值
<bean id="example" class="example.ComplexObject"> <property name="someList"> <list> <value>a list element followed by a reference</value> <ref bean="myDataSource"/> </list> </property> <property> <map> <entry key="one" value="the first"/> <entry key="two" value="the second"/> </map> </property> </bean>
Spring的5种作用域介绍:
参考http://my.oschina.net/itblog/blog/203436
Spring“注入”的注解:
在很多时候,我们都是用@Resource、@Required、@Autowired等注解来实现注入。但是还要向spring容器进行注册,AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、
PersistenceAnnotationBeanPostProcessor以及RequiredAnnotationBeanPostProcessor这4个BeanPostProcessor,我了实现方便,我们在applicationContext.xml中利用<context:component-scanbase-package=”XX.XX”/>这个自动扫描包来实现。