spring核心是依赖注入。本质就是通过配置
xml文件或
注解来自动生成你需要的对象,放在spring的大容器中。
spring是一个独立的框架,既可以用在java SE项目中,也可以用在 Web项目中。程序先创建bean容器,再调用bean容器的getBean()方法来获取Spring容器中的bean。
获得
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
会得到多个依赖的jar,见下图。
bean
这里的bean类似于JavaBean,但范围要宽的很多。spring就像一个大容器,帮我们创建好对象后放入了它的容器。所有由它创建的对象,都叫bean。
bean的作用域:
singleton
每次调用getBean(),都返回同一个对象;
prototype
每次调用getBean(),都返回新的对象;
request
针对每次HTTP请求,Web应用中才有效。
org.springframework.context.
ApplicationContext
spring生成的bean存放在此类中。
生成ApplicationContext的构造函数有:
FileSystemXmlApplicationContext 从当前项目位置算起,即src/目录的上层目录。
ClassPathXmlApplicationContext 从classes/开始算起。例子:
ApplicationContext ctx =new ClassPathXmlApplicationContext("com/likeyichu/aop/beans.xml");
org.springframework.beans.factory.BeanFactory.
getBean(String name, Class<T> requiredType)
通过此方法获取bean。
xml增强配置
可以让spring读取我们的
.properties文件。例子见下,注意用到的是org.springframework.beans.factory.config.
PropertyPlaceholderConfigurer。
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://115.28.88.166:3306/AliyunDB
jdbc.username=root3
占位
<bean id="jdbc"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="/WEB-INF/jdbc.properties" />
</bean>
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
</bean>
依赖注入
两种注入
设值注入:通过<property .../>元素驱动spring执行setter方法。
构造注入:通过<constructor-arg.../> 元素驱动Spring执行带参数的构造函数。
需要在bean类中实现所有private字段的setter方法。下面是示例spring配置。
<!-- 注入bean属性-->
<bean id="obj1" class="com.likeyichu.sample.Sample1" >
<property name="field1" value="value1" /><!-- 无论字段属于哪种基本数据类型,value="都需要加引号"-->
<property name="field2" value="value2" />
</bean>
<bean id="obj2" class="com.likeyichu.sample.Sample2" >
<property name="field1" ref="obj1" /> <!--属性注入,引用其他bean-->
</bean>
<!-- 注入bean构造函数-->
<bean id="obj3" class="com.likeyichu.sample.Sample3">
<constructor-arg value="123"/><!--第一个形参-->
<constructor-arg ref="obj1"/>
<constructor-arg ref="obj2"/>
</bean>
装配集合
<bean id="book" class="com.likeyichu.sample.Book">
<property name="bookList">
<list>
<ref bean="bean1"/>
<ref bean="bean2"/>
</list>
</property>
<property name="bookSet">
<set>
<ref bean="bean1"/>
<ref bean="bean2"/>
</set>
</property>
<property name="bookMap">
<map>
<entry key="book1" value-ref="bean1"/>
<entry key="book2" value-ref="bean2"/>
</map>
</property>
</bean>
初始化和销毁bean
当实例化一个bean时,可能需要执行一些初始化操作来确保该bean处于可用状态;同样地,当不再需要bean,将其从容器中移除时,我们还可能按顺序执行一些清除工作。此时我们需要init-method与destroy-method属性。
public class Stage{
public void turnOnLight(){
}
public void turnOffLight(){
}
}
<bean id="stage" class="com.likeyichu.Stage" init-method="turnOnLight" destroy-method="turnOfflight" />
自动装配
为了简化xml配置,spring提供了四种自动装配机制。
byName:把与bean的属性
同名的其他bean,自动装配到对应属性中;若找不到,不装配。
byType:把与bean的属性
同类型的其他bean,自动装配到对应属性中;若找不到,不装配。
constructor :把与bean的
构造函数形参
同类型的其他bean,自动装配到对应属性中;若找不到,不装配。
autodetect:尝试constructor装配,若失败,采用byType装配。
@注解
可以使用注解来代替xml配置。
@ org.springframework.stereotype.
Component
一个类若标注了@Component,表明此类被作为Spring的Bean类。对象名默认为
类名首字母小写。也可以@Component("name")来手动指定。
此外还有@Service、@Controller与@Repository。它们都有@Component的效果,只是为了方便人看,见名知意。
@Service用于标注业务层组件
@Controller用于标注控制层组件(如struts中的action)
@Repository用于标注数据访问组件,即DAO组件
@org.springframework.context.annotation.
Scope
指定bean的作用域,取值有singleton(默认值)、prototype。可以放在@Component注解的上一行。
@javax.annotation.
Resource
Spring直接用了java的标准注释。它与<Property />元素的ref属性有相同的结果。该注解可以放在setter方法前。
@
Autowored
大致等同于@Resource,这是spring自己的。
@
Inject
大致等同于@ResourceJava,这是依赖注入规范,比@Resource要新。
注解的自动扫描
<context:annotation-config>
Spring默认禁用注释,加上此标签才能启用。
它省掉了<propertiy>配置,但省不掉<bean>配置。
<context:component-scan>
它省掉了<bean>配置。
一个beans.xml及bean及app代码示例见下。注意版本号要与jar对应。
过滤组件扫描
可以省略@Conponent注释。
<!--自动扫描派生于Instrument乐器类下的bean,这些bean不需要@Component注释 -->
<context:component-scan base-package="com.likeyichu.resource">
<context:include-filter type="assignable" expression="com.likeyichu.resource.Instrument"/>
</context:component-scan>