zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    安装python包的两种方法
    Oracle 查询当前用户下的所有表
    Oracle SQL存储过程结构、异常处理示例
    Oracle IF-ELSE条件判断结构
    Oracle 组函数count()
    从svn下载项目后出现 Error:java: Compilation failed: internaljava compiler error 解决办法
    当学习失去方向,开始荒废时光时
    给自己一个目标
    汇编环境搭建在Linux下
    汇编学习总结
  • 原文地址:https://www.cnblogs.com/minihouseCoder/p/5612890.html
Copyright © 2011-2022 走看看