Java实战之03Spring-02Spring的核心之IoC

二、Spring的核心之IoC(Inversion of Control 控制反转)

1IoC是什么?

回顾:连接池原理中的使用。

注意:我们在连接池原理中是使用构造函数注入的,当然还可以通过提供set方法实现注入。

      

2Spring容器

Spring容器简单理解就是用于存放对象的。

3SpringIoC入门

3.1、建立一个java工程

3.2、导入Spring的核心jar

3.3、建立一个XML配置文件

1 <beans xmlns="http://www.springframework.org/schema/beans"
2        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3        xsi:schemaLocation="http://www.springframework.org/schema/beans 
4                               http://www.springframework.org/schema/beans/spring-beans.xsd">
5 </beans>

注意:现在xml文件用什么名字无所谓。

关于springxml文件没有提示的原因和解决办法,与struts2hibernate中相同。只是引入的约束前两个是dtd,而spring引入的schema约束。

3.4、资源交给Spring容器管理

 1 <!-- 把持久层和业务层的创建都交给spring来管理 
 2     bean元素用于配置程序中可重用的组件。包括持久层,业务层以及表现层动作类
 3     id属性指定的是spring容器中的key
 4     class属性指定的就是类的全名称
 5     spring容器在创建时,会读取配置文件,创建一个容器(map),把id作为key,把class属性创建的对象作为value,存入容器中
 6     
 7     在加载配置文件时,会反射创建类对象。调用的默认无参的构造函数
 8 -->
 9     <bean id="userDao" class="cn.itcast.dao.impl.UserDaoForMySQLImpl"></bean>
10     
11     <bean id="userService" class="cn.itcast.service.impl.UserServiceImpl">
12         <!-- 在service中,注入dao -->
13         <property name="userDao" ref="userDao"></property>
14     </bean>

3.5、Spring容器的初始化及资源的获取

 1 public static void main(String[] args) {
 2         /*
 3          * 1.加载配置文件,用于创建spring的容器(map)
 4          *     ClassPathXmlApplicationContext:表示配置文件在类路径下
 5          *  FileSystemXmlApplicationContext():当配置文件不在类路径下,而是在磁盘上时,使用此类加载。
 6          */
 7         ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
 8         //从容器中获取需要的对象:根据key取value
 9 //        IUserDao userDao = (IUserDao) ac.getBean("userDao");
10 //        System.out.println(userDao);
11         IUserService userService  = (IUserService) ac.getBean("userService");
12         System.out.println(userService);
13         userService.saveUser();
14     }

4、SpringAPI的体系结构

4.1、核心接口和类

BeanFactory:它使用的是延迟加载思想。当我们需要用bean时,才去创建对象。

ApplicationContext:它继承自BeanFactory接口,还继承了很多其他接口。功能比BeanFactory强大。它用的不是延迟加载思想,而是在加载配置文件时就创建了。(推荐)

FileSystemXmlApplicationContext:配置文件在本地磁盘上,使用该类加载。

ClassPathXmlApplicationContext :配置文件在classpath中,使用此类加载。

5、基于XMLspringIoC配置

5.1Spring实例化bean的方式

调用默认的构造方法 (推荐)

 1 <!-- 把持久层和业务层的创建都交给spring来管理 
 2     bean元素用于配置程序中可重用的组件。包括持久层,业务层以及表现层动作类
 3     id属性指定的是spring容器中的key
 4     class属性指定的就是类的全名称
 5     spring容器在创建时,会读取配置文件,创建一个容器(map),把id作为key,把class属性创建的对象作为value,存入容器中
 6     
 7     需要掌握:在加载配置文件时,会反射创建类对象。调用的默认无参的构造函数。如果没有提供无参构造的情况下,是不能实例化bean对象的
 8 -->
 9     <bean id="userDao" class="cn.itcast.dao.impl.UserDaoForMySQLImpl"></bean>
10     
11     <bean id="userService" class="cn.itcast.service.impl.UserServiceImpl"></bean>

5.2Bean的作用范围

 1 <!-- Bean的作用范围
 2     scope属性:
 3         取值:
 4             singleton:单例(默认值)
 5             prototype:多例
 6             request:请求范围
 7             session:会话范围
 8             global-session:集群的会话范围。
 9 -->
10     <bean id="userBean" class="cn.itcast.bean.UserBean1" scope="prototype">
11     </bean>

5.3、Bean的生命周期方法

 1 /**
 2  * 模拟一个Bean
 3  * @author zhy
 4  *
 5  */
 6 public class UserBean {
 7     
 8     //实例化
 9     public UserBean(){
10         System.out.println("实例化:大爷来也!");
11     }
12     //初始化
13     public void init(){
14         System.out.println("初始化:大爷准备好了");
15     }
16     //销毁
17     public void destroy(){
18         System.out.println("销毁:老夫休矣!");
19     }
20 
21     public void saveUser(){
22         System.out.println("业务方法:老夫只劫财不劫色");
23     }
24 }
 1 <beans xmlns="http://www.springframework.org/schema/beans"
 2        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3        xsi:schemaLocation="http://www.springframework.org/schema/beans 
 4                               http://www.springframework.org/schema/beans/spring-beans.xsd">
 5 <!-- Bean的生命周期 
 6      bean默认情况下是单例的,但是没有执行销毁方法。
 7      bean:出生 活着  死亡
 8       出生:在使用立即加载方式,spring容器一创建,bean对象就已经都创建好了。实例化bean和初始化bean就都执行了。
 9       活着:spring容器还在,bean对象就一直在。
10       死亡:spring容器如果没了,bean对象也就消亡了。
11 -->
12     <bean id="userBean" class="cn.itcast.bean.UserBean" init-method="init" destroy-method="destroy"></bean>
13 </beans>

注意:当非单例时,初始化方法正常执行,但是销毁方法就不会执行了。

5.4、依赖注入

a、构造器注入:通过传参数

 1 <!-- 第一种方式:是通过构造函数注入 
 2     使用construtor-arg
 3     常用属性:
 4         index:指定的是参数出现在构造函数中的索引
 5         type:指定参数在构造函数中的数据类型
 6         name:指定参数在构造函数中的名称        *****
 7         以上三个都是在指定:给谁注入
 8         
 9         value:注入基本数据类型或者String类型的值
10         ref:注入的是其他bean类型的值
11         以上两个都是在指定:注入的值
12 
13  当在定义bean时,使用了constructor-arg元素,则在bean元素中有几个constructor-arg,就需要提供对应参数列表的构造函数
14 -->
15     <bean id="userBean" class="cn.itcast.bean.UserBean1">
16         <constructor-arg name="name" value="test" ></constructor-arg>
17         <constructor-arg name="age" value="18"></constructor-arg>
18         <constructor-arg name="birthday" ref="now" ></constructor-arg>
19     </bean>

b、属性注入:推荐

 1 <!-- 第二种方式:是通过属性的set方法注入 
 2     需要使用的元素是:property
 3     属性:
 4         name:写的是set方法后面的部分,并且首字母转小写。
 5         ref:注入的其他Bean类型的值
 6         value:注入的是基本类型或者String类型的值
 7 -->    
 8     <bean id="userBean2" class="cn.itcast.bean.UserBean2">
 9         <property name="name" value="test" ></property>
10         <property name="age" value="18"></property>
11         <property name="birthday" ref="now"></property>
12     </bean>

c、p名称空间

 1 <beans xmlns="http://www.springframework.org/schema/beans"
 2        xmlns:p="http://www.springframework.org/schema/p"
 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.xsd">
 6 <!-- 使用p名称空间注入 
 7 1、导入P名称空间:xmlns:p="http://www.springframework.org/schema/p"
 8 2、在bean元素中使用p名称空间
 9     p:属性名称。
10     属性名称指的是set方法后面的部分。
11     每个属性都有两个赋值方式:
12         p:属性名称
13         p:属性名称-ref
14 -->
15     <bean id="userBean4" class="cn.itcast.bean.UserBean4" p:name="test" p:age="20" p:birthday-ref="now"></bean>
16 
17     <bean id="now" class="java.util.Date"></bean>

d、SpELSpring Expression Lanaguage

1 <!-- 使用Spring中EL表达式。SpringEL 目前定位:了解 
2     ${now}就是SPring的EL表达式
3 -->    
4     <bean id="userBean3" class="cn.itcast.bean.UserBean3">
5         <property name="name" value="test" ></property>
6         <property name="age" value="18"></property>
7         <property name="birthday" value="#{now}"></property>
8     </bean>

e、注入集合数据

 1 <!-- 注入集合数据 
 2     如果是对象集合数据,list结构的,可以使用如下三个元素:
 3         array
 4         list
 5         set
 6     如果是map结构的,可以使用如下四个元素
 7         map:
 8             map的子元素是entry
 9         props
10             props的子元素是prop
11     只要结构相同,元素可以互换。
12 -->
13     <bean id="userBean5" class="cn.itcast.bean.UserBean5">
14         <!-- 给数组注入值 -->
15         <property name="myStrs">
16             <list>
17                 <value>AAA</value>
18                 <value>BBB</value>
19                 <value>CCC</value>
20             </list>
21         </property>
22         <!-- 给List集合注入值 -->
23         <property name="myList">
24             <set>
25                 <value>AAA</value>
26                 <value>BBB</value>
27                 <value>CCC</value>
28             </set>
29         </property>
30         <!-- 给Set集合注入值 -->
31         <property name="mySet">
32             <array>
33                 <value>AAA</value>
34                 <value>BBB</value>
35                 <value>CCC</value>
36             </array>
37         </property>
38         <!-- 给map注入数据 -->
39         <property name="myMap">
40             <props>
41                 <prop key="testA">AAA</prop>
42                 <prop key="testB">BBB</prop>
43                 <prop key="testC">CCC</prop>
44             </props>
45         </property>
46         <!-- 给properties注入数据 -->
47         <property name="myProps">
48             <map>
49                 <entry key="AAA">
50                     <value>testA</value>
51                 </entry>
52                 <entry key="BBB" value="testB"></entry>
53                 <entry key="CCC">
54                     <value>testC</value>
55                 </entry>
56             </map>
57         </property>

5.5、团队开发:多个Spring配置文件

a、一次加载多个配置文件

1 public static void main(String[] args) {
2         ApplicationContext ac = new ClassPathXmlApplicationContext("bean1.xml","bean2.xml");
3         //获取bean对象
4         UserBean1 bean1 = (UserBean1)ac.getBean("userBean1");
5         bean1.saveUser();
6         
7         UserBean2 bean2 = (UserBean2)ac.getBean("userBean2");
8         bean2.saveUser();
9 }    

b、基于主从配置文件

1 <!-- Spring的多配置文件
2     引入其他的配置
3 -->
4 <import resource="bean1.xml"/>
5 <import resource="bean2.xml"/>

c、注意事项

同一个配置文件中不能出现bean元素id属性取值相同的:

不同文件中bean元素id属性取值相同时,有加载顺序

使用beanname属性获取bean对象(了解就行)

6、基于注解的springIoC配置

6.1、注解的使用前提

a、引入context的名称空间

b、指定要扫描的包

c、在Bean上面加入@Component注解

 1 @Component("userBean")
 2 //就相当于在配置文件中配置<bean id="userBean" class="cn.itcast.bean.UserBean" />
 3 public class UserBean {
 4     
 5     @Value(value="test")
 6     private String name;
 7 
 8     public void saveUser(){
 9         System.out.println("业务方法:老夫只劫财不劫色");
10         System.out.println(name);
11     }
12 }

b@Component的衍生注解@Controller@Service@Repository

作用:和@Component作用一样,让Spring容器管理(实例化)当前的bean

属性: value:指定bean的名称。默认值是当前类的简单类名首字母小写

特点:在三成架构中,每个注解对应一层,使语义更加明确。

@Controller一般用在表现层,比如struts2action

@Service一般用在业务层,比如Service实现

@Repository一般用在持久层,比如Dao实现

 1 @Repository("userDaoForMySQL")
 2 public class UserDaoForMySQLImpl implements IUserDao {
 3 
 4 
 5     public void saveUser() {
 6         System.out.println("MySQL:保存了用户");
 7     }
 8 
 9     public void deleteUser() {
10         System.out.println("MySQL:删除了用户");
11     }
12 
13 }
14 @Service("userService")
15 public class UserServiceImpl implements IUserService {
16     
17     public void saveUser() {
18         System.out.println("UserServiceImpl的savaUser方法执行了");
19         userDao.saveUser();
20     }
21 
22     public void deleteUser() {
23         userDao.deleteUser();
24     }
25 
26 }
27 @Controller("userAction")
28 public class UserAction {
29     
30     public String saveUser(){
31         System.out.println("UserAction的savaUser方法执行了");
32         userService.saveUser();
33         return null;
34     }
35 }

c@Autowired

作用:自动按类型注入需要的对象。当使用了该注解时,setter就不是必须的了。

属性:

required:是否必须注入成功。默认值是true

true:必须注入成功,如果出现注入失败,抛出异常。

false:不一定注入成功,不抛异常。

注意事项:

一个Service接口:IBookService

两个Service实现:BookServiceImpl1  BookServiceImpl2

由于@Autowired是自动按类型注入,当使用接口类型时,就看变量的名称,如果变量名称是bookServiceImpl1,则使用BookServiceImp1这个实现类,

如果变量名是bookServiceImpl2,则使用BookServiceImpl2这个实现类。如果没有符合规范的名称(类名首字母小写),则报错。

到底注入哪个实现类:

@Autowried

private BookService bookServiceImpl1;//注入BookServiceImpl1  

@Autowried

private BookService bookServiceImpl2;//注入BookServiceImpl2  

@Autowried

private BookService bookService;//注入失败

d@Value

作用:注入基本类型和String。

属性:value:SpEL表达式,要注入的值

e@Qualifier

作用:要配合@Autowried来一起使用,通过它指定要注入的bean的名称。按类型注入失效了。

属性:value:要注入的bean的名称

f@Resource

作用:如同@Autowire和@Qualifier,是规范JSR-250中定义的(JCP)。通过指定bean的名称注入对象。

属性: name:要注入的bean的名称

g@PostConstruct(了解)

作用:用在初始化方法上。生命周期有关

h@PreDestroy(了解)

作用:用在销毁方法上。生命周期有关

i@Configuration@Bean(了解)

作用:@Configuration指定当前类为配置类,用于加载@Bean的定义。@Bean用于定义bean的名称,用法是@Bean(name="beanName")

注意:该类要被设置在注解自动扫描对应的包下。

6.3Spring中使用单元测试

a、导入jar包:

spring-test-3.2.0.RELEASE.jar

b、设置Junit运行器和Spring配置文件

 1 /**
 2  * Spring整合Junit
 3  * 1、导入junit的jar包。导入spring整合junit的jar包
 4  * 2、要替换运行器(其实就是测试用的main函数),换成spring框架提供的,因为只有spring框架提供的才能支持spring。
 5  * 3、告知新运行器,spring的配置文件所在的位置
 6  * @author zhy
 7  *
 8  */
 9 @RunWith(SpringJUnit4ClassRunner.class)
10 @ContextConfiguration(locations={"classpath:bean.xml"})
11 public class UserBeanTest {
12 
13     @Autowired
14     private UserBean userBean;
15     
16     @Test
17     public void testSaveUser(){    
18         userBean.saveUser();
19     }
20 }
posted @ 2016-06-24 01:06  铭昊Coder  阅读(389)  评论(0编辑  收藏  举报