Spring IOC的快速入门
开发步骤:
-
引入Spring的jar包 在pom.xml中
<!--引入Spring 的jar包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.2.4.RELEASE</version> </dependency> <!--引入日志的jar包--> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <!--log4j--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
-
编写Spring的配置文件 默认名为 :applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <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.xsd"> <!--IOC :反转控制 UserService的创建权交给了Spring --> <bean id="userService" class="com.tao.ioc.demo1.UserServiceImpl"> <!--DI :依赖注入 设置属性--> <property name="name" value="李四"/> </bean> </beans>
-
在测试类中
-
创建Spring的工厂
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“applicationContext.xml”);
-
通过工厂获得类
applicationContext.getBean(“userService”);
-
调用该类的方法
public void demo2(){ //创建Spring的工厂 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); //通过工厂获得类 此处的userService即为applicationContext.xml中的bean标签下的id UserService userService = (UserService) applicationContext.getBean("userService"); //调用方法 userService.sayHello(); }
-
IOC与DI
-
IOC:反转控制,将创建对象的控制权反转到Spring框架
<!-- UserService的创建权交给了Spring --> <bean id="userService" class="com.tao.ioc.demo1.UserServiceImpl"></bean>
-
DI:依赖注入,在Spring创建这个对象的过程中,将这个对象所依赖的属性注入进去
<!--DI :依赖注入 设置属性--> <property name="name" value="李四"/>
注意:是先有IOC,后有DI
Spring的Bean管理(XML的方式)
-
三种实例化Bean的方式
一般情况下使用无参构造的方式,参数比较复杂时可以采用第二、三种方式
-
使用类构造器实例化(默认无参数)
-
使用静态工厂方法实例化(简单工厂模式)
-
使用实例工厂方法实例化(工厂方法模式)
applicationContext.xml
<!--Bean的实例化的三种方式=================--> <!--第一种方式:无参构造器的方式--> <bean id="bean1" class="com.tao.ioc.demo3.Bean1"/> <!--第二种方式:静态工厂的方式--> <bean id="bean2" class="com.tao.ioc.demo3.Bean2Factory" factory-method="creatBean2"/> <!--第三种方式:实例工厂的方式--> <bean id="bean3Factory" class="com.tao.ioc.demo3.Bean3Factory"/> <bean id="bean3" factory-bean="bean3Factory" factory-method="createBean3"/>
测试方法
/** * Bean的实例化的三种方式 */ public class SpringDemo3 { @Test //方式一:无参构造器的方式 public void demo1(){ //创建工厂 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); //通过工厂获得类的实例 Bean1 bean1 = (Bean1) applicationContext.getBean("bean1"); } @Test //方式二:静态工厂的方式 public void demo2(){ //创建工厂 当该工厂类一加载,就会将applicationContext.xml该文件中的都实例化 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); //通过工厂获得类的实例 Bean2 bean2 = (Bean2) applicationContext.getBean("bean2"); } @Test //方式三:实例工厂的方式 public void demo3(){ //创建工厂 当该工厂类一加载,就会将applicationContext.xml该文件中的都实例化 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); //通过工厂获得类的实例 Bean3 bean3 = (Bean3) applicationContext.getBean("bean3"); } }
Bean的配置
-
id和name
– 一般情况下,装配一个Bean时,通过指定一个id属性作为Bean的名称
– id属性在IOC容器中必须是唯一的
– 如果Bean的名称中含有特殊字符,就需要使用name属性 (id 和 name 一样,只是含有特殊字符时需要用name)- class
– class用于设置一个类的完全路径名称,主要作用是IOC容器生成类的实例
Bean的作用域 scope属性
类别 说明 singleton 在SpringIOC容器中仅存在一个Bean实例,Bean以单实例的方式存在 默认值 prototype 每次调用getBean()时都会返回一个新的实例 request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境 session 同一个HTTP Session共享一个Bean,不同的HTTPSession使用不同的Bean。该作用域仅适用于WebApplicationContext环境 -
-
Spring容器中的Bean的生命周期
Spring初始化bean或销毁bean时,有时需要做一些处理工作,因此spring可以在创建和销毁bean的时候调用bean的两个生命周期方法。
<bean id="xxx" class="....Yoo"
init-method="init"
destory-method="destory">
</bean>
<!--当bean被载入到容器的时候调用init 当bean从容器中删除的时候调用destory(scope=singleton有效,即单例模式时有效)-->
Spring的完整生命周期
《关键的是第五步和第八步》
1.instantiate bean对象实例化
2.populate properties 封装属性
3.如果Bean实现BeanNameAware 执行setBeanName
4.如果Bean实现BeanFactoryAware或者ApplicationContextAware设置工厂setBeanFactory或者上下文对象setApplicationContext
5.如果存在类实现BeanPostProcessor(后处理Bean ),执行postProcessBeforeInitialization
6.如果Bean实现InitializingBean 执行afterPropertiesSet
7.调用指定初始化方法init
8.如果存在类实现BeanPostProcessor(处理Bean ),执行 postProcessAfterInitialization
9.执行业务处理
10.如果Bean实现DisposableBean 执行destroy
11.调用指定销毁方法customerDestroy
applicationContext.xml
<!--Bean的生命周期================-->
<bean id="man" class="com.tao.ioc.demo4.Man" init-method="steup" destroy-method="teardown">
<property name="name" value="张三"></property>
</bean>
<bean class="com.tao.ioc.demo4.MyBeanPostProcessor"/>
Man.java
public class Man implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
private String name;
public String getName() {
return name;
}
public Man(){
System.out.println("第一步:MAN被实例化了...");
}
public void setName(String name) {
System.out.println("第二步:设置属性,并在applicationContext.xml中设置属性标签");
this.name = name;
}
@Override
public void setBeanName(String s) {
System.out.println("第三步:设置Bean的名称" + name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("第四步:了解工厂的信息");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("第六步:属性设置后");
}
public void steup(){
System.out.println("第七步:MAN被初始化了...");
}
public void run(){
System.out.println("第九步:执行自身的业务方法");
}
@Override
public void destroy() throws Exception {
System.out.println("第十步:执行Spring的销毁方法");
}
public void teardown(){
System.out.println("第十一步:自己配置的销毁方法MAN被销毁...");
}
}
MyBeanPostProcessor.java
public class MyBeanPostProcessor implements BeanPostProcessor {
//初始化前
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第五步:初始化前方法");
return bean;
}
//初始化后
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第八步:初始化后方法");
return bean;
}
}
Spring的属性注入 DI
-
对于类成员变量,注入方式有三种:
-
构造函数注入
-
通过构造方法注入Bean的属性值或依赖的对象,它保证了Bean实例在实例化后就可以使用
-
构造器注入在 元素里声明的属性
applicationContext.xml中 <!--Spring的属性注入--> <!--方式一:构造方法的属性注入--> <bean id="user" class="com.tao.ioc.demo5.User"> <constructor-arg name="name" value="张三"/> <constructor-arg name="age" value="23"/> </bean>
-
-
属性setter方法注入
-
使用set方法注入,在Spring配置文件中,通过设置注入的属性
<!--方式二:set方法的属性注入--> <bean id="person" class="com.tao.ioc.demo5.Person"> <property name="name" value="李四"/> <property name="age" value="21"/> <property name="cat" ref="cat"/> <!--普通类型的值使用value,对象类型的值使用ref ref指向的是id--> </bean> <bean id="cat" class="com.tao.ioc.demo5.Cat"> <property name="name" value="油条"/> </bean>
-
-
-
接口注入
注意:Spring只支持前两种
-
P名称空间属性注入
- 使用p命名空间
- 为了简化XML文件配置,Spring从2.5开始引入一个新的名称空间
- p:<属性名>=“xxx” 引入常量值
- p:<属性名>-ref=“xxx” 引用其他Bean对象
-
Spring的属性注入—SpEL注入
-
SpEL : spring expression language , spring表达式语言,对依赖注入进行简化
-
语法︰#{表达式}
- SpEL表达式语言
语法∶#{}
#{ ‘hello’ } : 使用字符串
#{ beanId } : 使用另一个bean
#{beanld.content.toUpperCase()}:使用指定名属性,并使用方法
#{ T (java.lang.Math).PI }∶使用静态字段或方法
-
复杂类型的属性注入
- 数组类型的属性注入
- List集合类型的属性注入
- Set集合类型的属性注入
- Map集合类型的属性注入
- Properties类型的属性注入
<!--复杂类型的属性注入 / 集合类型的属性注入==============-->
<bean id="collectionBean" class="com.tao.ioc.demo6.CollectionBean">
<!--数组类型-->
<property name="arrs">
<list>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</list>
</property>
<!--List集合的属性注入-->
<property name="list">
<list>
<value>111</value>
<value>222</value>
<value>333</value>
</list>
</property>
<!--Set集合的属性注入-->
<property name="set">
<set>
<value>ddd</value>
<value>eee</value>
<value>fff</value>
</set>
</property>
<!--Map集合的属性注入-->
<property name="map">
<map>
<entry key="aaa" value="111"/>
<entry key="bbb" value="222"/>
<entry key="ccc" value="333"/>
</map>
</property>
<!--Properties类型的属性注入-->
<property name="properties">
<props>
<prop key="username">root</prop>
<prop key="password">12345</prop>
</props>
</property>
</bean>
Spring的Bean管理-----注解的方式
-
Spring2.5引入使用注解去定义Bean
- @Component描述Spring框架中Bean
-
除了@Component外,Spring提供了3个功能基本和@Component等效的注解
-
@Repository用于对DAO实现类进行标注
-
@Service用于对Service实现类进行标注
-
@Controller用于对Controller实现类进行标注
-
属性注入的注解
- 使用@Autowired进行自动注入
- @Autowired默认按照类型进行注入
— 如果存在两个相同Bean类型相同,则按照名称注入 - @Autowired注入时可以针对成员变量或者set方法
- 通过@Autowired的required属性,设置一定要找到匹配的Bean
- 使用@Qualifier指定注入Bean的名称
- 使用Qualifier指定Bean名称后,注解Bean必须指定相同名称
- Spring提供对JSR-250中定义@Resource标准注解的支持
- @Resource和@Autowired注解功能相似
Spring的其他注解
-
Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。
<bean id="xxx" class="...Yoo" init-method="init" destroy-method="destroy" /> <!--当bean被载入到容器的时候调用init 当bean从容器中删除的时候调用destroy(scope=singleton有效) 注解方式如下: @PostConstruct 注解方式如下: @PreDestroy 初始化 销毁 -->
Bean的作用范围
- 使用注解配置的Bean和配置的一样,默认作用范围都是singleton
- @Scope注解用于指定Bean的作用范围
XML配置与注解的整合开发
- 引入context命名空间
- 在配置文件中添加context:annotation-config标签 < context:annotation-config /> :可以使用属性注入的配置
XML管理类,注解管理属性