Spring3-IoC1-IoC容器、基于xml管理bean

打印 上一主题 下一主题

主题 517|帖子 517|积分 1551

目次
IoC容器
概述
依赖注入
IoC容器在Spring中的实现
基于xml管理bean
获取bean
依赖注入
setter注入
构造器注入
特殊值处理
字面量赋值
null值
xml实体
CDATA节
特殊范例属性注入
对象范例属性注入
方式一:引用外部bean
方式二:内部bean
方式三:级联属性赋值
数组范例属性注入
集合范例属性注入
list、set集合范例
map集合范例
引用集合范例 
p命名空间
引入外下属性文件
bean的作用域
bean的生命周期
FactoryBean
基于xml自动装配

IoC容器

概述

IoC 是 Inversion of Control 的简写,译为“控制反转”,它不是一门技术,而是一种计划思想,是一个告急的面向对象编程法则,可以或许指导我们怎样计划出松耦合、更优良的步伐
Spring 通过 IoC 容器来管理全部 Java 对象的实例化和初始化,控制对象与对象之间的依赖关系。我们将由 IoC 容器管理的 Java 对象称为 Spring Bean,它与使用关键字 new 创建的 Java 对象没有任何区别
控制反转是一种思想
控制反转是为了低落步伐耦合度,提高步伐扩展力
控制反转,反转的是什么?


  • 将对象的创建权利交出去,交给第三方容器负责
  • 将对象和对象之间关系的维护权交出去,交给第三方容器负责
控制反转这种思想怎样实现呢?


  • DI(Dependency Injection):依赖注入  
依赖注入

DI(Dependency Injection):依赖注入,依赖注入实现了控制反转的思想
依赖注入:Spring创建对象的过程中,将对象依赖属性通过配置进行注入
依赖注入常见的实现方式包括两种:


  • set注入
  • 构造注入
Bean管理:Bean对象的创建以及Bean对象中属性的赋值(或者叫做Bean对象之间关系的维护)
IoC容器在Spring中的实现

Spring 的 IoC 容器就是 IoC思想的一个落地的产物实现。IoC容器中管理的组件也叫做 bean。在创建 bean 之前,起首需要创建IoC 容器。Spring 提供了IoC 容器的两种实现方式:
①BeanFactory
这是 IoC 容器的根本实现,是 Spring 内部使用的接口。面向 Spring 本身,不提供给开发人员使用
②ApplicationContext
BeanFactory 的子接口,提供了更多高级特性。面向 Spring 的使用者,几乎全部场合都使用ApplicationContext,而不是底层的 BeanFactory
ApplicationContext的主要实现类:
范例名简介ClassPathXmlApplicationContext通过读取类路径下的 XML 格式的配置文件创建 IOC 容器对象FileSystemXmlApplicationContext通过文件系统路径读取 XML 格式的配置文件创建 IOC 容器对象ConfigurableApplicationContextApplicationContext 的子接口,包含一些扩展方法 refresh() 和 close() ,让 ApplicationContext 具有启动、关闭和刷新上下文的本领WebApplicationContext专门为 Web 应用准备,基于 Web 环境创建 IOC 容器对象,并将对象引入存入 ServletContext 域中 基于xml管理bean

依赖放入父模块
创建新模块spring-ioc-xml
  1. package com.qcby.spring;
  2. public class User {
  3.     private String name;
  4.     private Integer age;
  5.     public void run(){
  6.         System.out.println("run...");
  7.     }
  8. }
复制代码
获取bean

①方式一:根据id获取
由于 id 属性指定了 bean 的唯一标识,以是根据 bean 标签的 id 属性可以精确获取到一个组件对象(入门案例)
bean.xml:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.     <!--user对象创建-->
  6.     <bean id="user" class="com.qcby.spring.User"></bean>
  7. </beans>
复制代码
测试类: 
  1. package com.qcby.spring;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class TestUser {
  5.     public static void main(String[] args) {
  6.         ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
  7.         //根据id获取bean
  8.         User user = (User) context.getBean("user");
  9.         System.out.println("根据id获取bean:"+user);
  10.     }
  11. }
复制代码

②方式二:根据范例获取
  1. package com.qcby.spring;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class TestUser {
  5.     public static void main(String[] args) {
  6.         ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
  7.         //根据id获取bean
  8. //        User user = (User) context.getBean("user");
  9. //        System.out.println("根据id获取bean:"+user);
  10.         //根据类型获取bean
  11.         User user = context.getBean(User.class);
  12.         System.out.println("根据类型获取bean"+user);
  13.     }
  14. }
复制代码

当根据范例获取bean时,要求IOC容器中指定范例的bean有且只能有一个 
若配置多个,会抛出异常:org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type
③方式三:根据id和范例
  1. package com.qcby.spring;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class TestUser {
  5.     public static void main(String[] args) {
  6.         ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
  7.         //根据id获取bean
  8. //        User user = (User) context.getBean("user");
  9. //        System.out.println("根据id获取bean:"+user);
  10.         //根据类型获取bean
  11. //        User user = context.getBean(User.class);
  12. //        System.out.println("根据类型获取bean"+user);
  13.         //根据id和类型获取bean
  14.         User user = context.getBean("user", User.class);
  15.         System.out.println("根据id和类型获取bean:"+user);
  16.     }
  17. }
复制代码

扩展:
如果组件类实现了接口,根据接口范例可以获取 bean 吗?


  • 可以,前提是bean唯一
  1. package com.qcby.spring;
  2. public interface UserDao {
  3.     public void run();
  4. }
复制代码
  1. package com.qcby.spring;
  2. public class UserDaoImpl implements UserDao{
  3.     @Override
  4.     public void run() {
  5.         System.out.println("run...");
  6.     }
  7. }
复制代码
  1. <!--一个接口获取类过程-->
  2. <bean id="userDaoImpl" class="com.qcby.spring.bean.UserDaoImpl.UserDaoImpl"></bean>
复制代码
  1. package com.qcby.spring;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class TestUserDao {
  5.     public static void main(String[] args) {
  6.         ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
  7.         //根据类型获取接口对应bean
  8.         UserDao userDao = context.getBean(UserDao.class);
  9.         System.out.println(userDao);
  10.         userDao.run();
  11.     }
  12. }
复制代码



如果一个接口有多个实现类,这些实现类都配置了 bean,根据接口范例可以获取 bean 吗?


  • 不可,因为bean不唯一
依赖注入

setter注入

第一步:创建类,天生属性set方法
第二步:在spring配置文件配置
  1. package com.qcby.spring.di;
  2. public class Book {
  3.     private String bname;
  4.     private String author;
  5.     //无参构造
  6.     public Book() {
  7.     }
  8.     //有参构造
  9.     public Book(String bname, String author) {
  10.         this.bname = bname;
  11.         this.author = author;
  12.     }
  13.     //生成get和set方法
  14.     public void setBname(String bname) {
  15.         this.bname = bname;
  16.     }
  17.     public void setAuthor(String author) {
  18.         this.author = author;
  19.     }
  20.     public String getBname() {
  21.         return bname;
  22.     }
  23.     public String getAuthor() {
  24.         return author;
  25.     }
  26.     @Override
  27.     public String toString() {
  28.         return "Book{" +
  29.                 "bname='" + bname + '\'' +
  30.                 ", author='" + author + '\'' +
  31.                 '}';
  32.     }
  33. }
复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
  5.     <!--set方法注入-->
  6.     <!-- property标签:通过组件类的setXxx()方法给组件对象设置属性 -->
  7.     <!-- name属性:指定属性名(这个属性名是getXxx()、setXxx()方法定义的,和成员变量无关) -->
  8.     <!-- value属性:指定属性值 -->
  9.     <bean id="book" class="com.qcby.spring.di.Book">
  10.         <property name="bname" value="前端开发"></property>
  11.         <property name="author" value="张三"></property>
  12.     </bean>
  13. </beans>
复制代码
  1. package com.qcby.spring;
  2. import com.qcby.spring.di.Book;
  3. import org.junit.Test;
  4. import org.springframework.context.ApplicationContext;
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;
  6. public class TestBook {
  7.     @Test
  8.     public void testSetter(){
  9.         ApplicationContext context = new ClassPathXmlApplicationContext("bean_di.xml");
  10.         Book book = context.getBean("book", Book.class);
  11.         System.out.println(book);
  12.     }
  13. }
复制代码

构造器注入

第一步:创建类,定义属性,天生有参构造方法
第二步:在spring配置文件配置
  1.     <!--构造器注入-->
  2.     <bean id="bookCon" class="com.qcby.spring.di.Book">
  3.         <constructor-arg name="bname" value="java开发"></constructor-arg>
  4.         <constructor-arg name="author" value="李四"></constructor-arg>
  5.     </bean>
复制代码
留意:
constructor-arg标签还有两个属性可以进一步描述构造器参数:


  • index属性:指定参数所在位置的索引(从0开始)
  • name属性:指定参数名
  1.     @Test
  2.     public void testCon(){
  3.         ApplicationContext context = new ClassPathXmlApplicationContext("bean_di.xml");
  4.         Book book = context.getBean("bookCon", Book.class);
  5.         System.out.println(book);
  6.     }
复制代码

特殊值处理

字面量赋值

什么是字面量?
int a = 10;
声明一个变量a,初始化为10,此时a不代表字母a,而是作为一个变量的名字。当引用a的时候,实际上拿到的值是10。
而如果a是带引号的:'a',那么它如今不是一个变量,它就是代表a这个字母本身,这就是字面量。以是字面量没有引申含义,就是我们看到的这个数据本身
  1. <!-- 使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量 -->
  2. <property name="name" value="张三"/>
复制代码
null值

  1. <property name="name">
  2.     <null />
  3. </property>
复制代码
留意:以下写法为name所赋的值是字符串null
  1. <property name="name" value="null"></property>
复制代码
xml实体

  1. <!-- 小于号在XML文档中用来定义标签的开始,不能随便使用 -->
  2. <!-- 解决方案一:使用XML实体来代替 -->
  3. <property name="expression" value="a &lt; b"/>
复制代码
CDATA节

  1. <property name="expression">
  2.     <!-- 解决方案二:使用CDATA节 -->
  3.     <!-- CDATA中的C代表Character,是文本、字符的含义,CDATA就表示纯文本数据 -->
  4.     <!-- XML解析器看到CDATA节就知道这里是纯文本,就不会当作XML标签或属性来解析 -->
  5.     <!-- 所以CDATA节中写什么符号都随意 -->
  6.     <value><![CDATA[a < b]]></value>
  7. </property>
复制代码
特殊范例属性注入

对象范例属性注入


  1. package com.qcby.spring.ditest;
  2. //部门类
  3. public class Dept {
  4.     private String dname;
  5.     public void info(){
  6.         System.out.println("部门名称:"+dname);
  7.     }
  8.     public void setDname(String dname) {
  9.         this.dname = dname;
  10.     }
  11.     public String getDname() {
  12.         return dname;
  13.     }
  14. }
复制代码
  1. package com.qcby.spring.ditest;
  2. //员工类
  3. public class Emp {
  4.     //对象类型属性:员工属于某个部门
  5.     private Dept dept;
  6.     private String ename;
  7.     private Integer age;
  8.     public void work(){
  9.         System.out.println(ename+"emp work..."+age);
  10.         dept.info();
  11.     }
  12.     public Dept getDept() {
  13.         return dept;
  14.     }
  15.     public void setDept(Dept dept) {
  16.         this.dept = dept;
  17.     }
  18.     public String getEname() {
  19.         return ename;
  20.     }
  21.     public void setEname(String ename) {
  22.         this.ename = ename;
  23.     }
  24.     public Integer getAge() {
  25.         return age;
  26.     }
  27.     public void setAge(Integer age) {
  28.         this.age = age;
  29.     }
  30. }
复制代码
方式一:引用外部bean

使用ref属性
  1.     <!--方式一:引入外部bean
  2.       1.创建两个类对象:dept emp
  3.       2.在emp的bean标签里,使用property引入dept的bean
  4.     -->
  5.     <bean id="dept" class="com.qcby.spring.ditest.Dept">
  6.         <property name="dname" value="安保部"></property>
  7.     </bean>
  8.     <bean id="emp" class="com.qcby.spring.ditest.Emp">
  9.         <!--普通属性注入-->
  10.         <property name="ename" value="lucy"></property>
  11.         <property name="age" value="50"></property>
  12.         <!--对象属性注入
  13.         ref属性:引用IOC容器中某个bean的id,将所对应的bean为属性赋值-->
  14.         <property name="dept" ref="dept"></property>
  15.     </bean>
复制代码

方式二:内部bean

  1.     <!--方式二:内部bean-->
  2.     <!-- 在一个bean中再声明一个bean就是内部bean -->
  3.     <!-- 内部bean只能用于给属性赋值,不能在外部通过IOC容器获取,因此可以省略id属性 -->
  4.     <bean id="emp2" class="com.qcby.spring.ditest.Emp">
  5.         <!--普通属性注入-->
  6.         <property name="ename" value="mary"></property>
  7.         <property name="age" value="20"></property>
  8.         <!--对象属性注入-->
  9.         <property name="dept">
  10.             <bean id="dept2" class="com.qcby.spring.ditest.Dept">
  11.                 <property name="dname" value="财务部"></property>
  12.             </bean>
  13.         </property>
  14.     </bean>
复制代码

方式三:级联属性赋值

  1.     <!--方式三:级联赋值-->
  2.     <bean id="dept3" class="com.qcby.spring.ditest.Dept">
  3.         <property name="dname" value="研发部"></property>
  4.     </bean>
  5.     <bean id="emp3" class="com.qcby.spring.ditest.Emp">
  6.         <!--普通属性注入-->
  7.         <property name="ename" value="tom"></property>
  8.         <property name="age" value="30"></property>
  9.         <!--对象属性注入-->
  10.         <property name="dept" ref="dept3"></property>
  11.         <property name="dept.dname" value="测试部"></property>
  12.     </bean>
复制代码

数组范例属性注入

员工类:
  1.     //爱好
  2.     private String[] loves;
  3.     public String[] getLoves() {
  4.         return loves;
  5.     }
  6.     public void setLoves(String[] loves) {
  7.         this.loves = loves;
  8.     }
  9.     public void work(){
  10.         System.out.println(ename+"emp work..."+age);
  11.         dept.info();
  12.         System.out.println(Arrays.toString(loves));
  13.     }
复制代码
  1.         <!--数组类型属性-->
  2.         <property name="loves">
  3.             <array>
  4.                 <value>吃饭</value>
  5.                 <value>睡觉</value>
  6.                 <value>看电影</value>
  7.             </array>
  8.         </property>
复制代码
完整的配置文件:
  1. <?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">    <bean id="dept" class="com.qcby.spring.ditest.Dept">        <property name="dname" value="技术部"></property>    </bean>    <bean id="emp" class="com.qcby.spring.ditest.Emp">        <!--普通属性-->        <property name="ename" value="lucy"></property>        <property name="age" value="20"></property>        <!--对象范例属性-->        <property name="dept" ref="dept"></property>        <!--数组类型属性-->
  2.         <property name="loves">
  3.             <array>
  4.                 <value>吃饭</value>
  5.                 <value>睡觉</value>
  6.                 <value>看电影</value>
  7.             </array>
  8.         </property>     </bean></beans>
复制代码

集合范例属性注入

list、set集合范例

Dept类:
  1.     private List<Emp> empList;
  2.    
  3.     public void info(){
  4.         System.out.println("部门名称:"+dname);
  5.         for (Emp emp : empList) {
  6.             System.out.println(emp.getEname());
  7.         }
  8.     }
  9.     public List<Emp> getEmpList() {
  10.         return empList;
  11.     }
  12.     public void setEmpList(List<Emp> empList) {
  13.         this.empList = empList;
  14.     }
  15. }
复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.     <bean id="empone" class="com.qcby.spring.ditest.Emp">
  6.         <property name="ename" value="lucy"></property>
  7.         <property name="age" value="20"></property>
  8.     </bean>
  9.     <bean id="emptwo" class="com.qcby.spring.ditest.Emp">
  10.         <property name="ename" value="mary"></property>
  11.         <property name="age" value="30"></property>
  12.     </bean>
  13.     <bean id="dept" class="com.qcby.spring.ditest.Dept">
  14.         <property name="dname" value="技术部"></property>
  15.         <property name="empList">
  16.             <list>
  17.                 <ref bean="empone"></ref>
  18.                 <ref bean="emptwo"></ref>
  19.             </list>
  20.         </property>
  21.     </bean>
  22. </beans>
复制代码
若为Set集合范例属性赋值,只需要将其中的list标签改为set标签即可  

map集合范例

Student和Teacher类:
  1. package com.qcby.spring.dimap;
  2. import java.util.Map;
  3. public class Student {
  4.     private Map<String,Teacher> teacherMap;
  5.     private String sid;
  6.     private String sname;
  7.     public void run(){
  8.         System.out.println("学生编号:"+sid+"学生名称:"+sname);
  9.         System.out.println(teacherMap);
  10.     }
  11.     public Map<String, Teacher> getTeacherMap() {
  12.         return teacherMap;
  13.     }
  14.     public void setTeacherMap(Map<String, Teacher> teacherMap) {
  15.         this.teacherMap = teacherMap;
  16.     }
  17.     public String getSid() {
  18.         return sid;
  19.     }
  20.     public void setSid(String sid) {
  21.         this.sid = sid;
  22.     }
  23.     public String getSname() {
  24.         return sname;
  25.     }
  26.     public void setSname(String sname) {
  27.         this.sname = sname;
  28.     }
  29. }
复制代码
  1. package com.qcby.spring.dimap;
  2. public class Teacher {
  3.     private String teacherId;
  4.     private String teacherName;
  5.     public String getTeacherId() {
  6.         return teacherId;
  7.     }
  8.     public void setTeacherId(String teacherId) {
  9.         this.teacherId = teacherId;
  10.     }
  11.     public String getTeacherName() {
  12.         return teacherName;
  13.     }
  14.     public void setTeacherName(String teacherName) {
  15.         this.teacherName = teacherName;
  16.     }
  17.     @Override
  18.     public String toString() {
  19.         return "Teacher{" +
  20.                 "teacherId='" + teacherId + '\'' +
  21.                 ", teacherName='" + teacherName + '\'' +
  22.                 '}';
  23.     }
  24. }
复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.     <!--
  6.       1.创建两个对象
  7.       2.注入普通类型属性
  8.       3.在学生bean注入map集合类型属性
  9.     -->
  10.     <bean id="teacherone" class="com.qcby.spring.dimap.Teacher">
  11.         <!--注入普通类型属性-->
  12.         <property name="teacherId" value="100"></property>
  13.         <property name="teacherName" value="讲师1"></property>
  14.     </bean>
  15.     <bean id="teachertwo" class="com.qcby.spring.dimap.Teacher">
  16.         <!--注入普通类型属性-->
  17.         <property name="teacherId" value="200"></property>
  18.         <property name="teacherName" value="讲师2"></property>
  19.     </bean>
  20.     <bean id="student" class="com.qcby.spring.dimap.Student">
  21.         <!--注入普通类型属性-->
  22.         <property name="sid" value="2000"></property>
  23.         <property name="sname" value="李四"></property>
  24.         <!--在学生bean注入map集合类型属性-->
  25.         <property name="teacherMap">
  26.             <map>
  27.                 <entry>
  28.                     <!--key-->
  29.                     <key>
  30.                         <value>1</value>
  31.                     </key>
  32.                     <!--value为对象-->
  33.                     <ref bean="teacherone"></ref>
  34.                 </entry>
  35.                 <entry>
  36.                     <!--key-->
  37.                     <key>
  38.                         <value>2</value>
  39.                     </key>
  40.                     <!--value为对象-->
  41.                     <ref bean="teachertwo"></ref>
  42.                 </entry>
  43.             </map>
  44.         </property>
  45.     </bean>
  46. </beans>
复制代码

引用集合范例 

Lesson类:
  1. package com.qcby.spring.dimap;
  2. public class Lesson {
  3.     private String lessonName;
  4.     public String getLessonName() {
  5.         return lessonName;
  6.     }
  7.     public void setLessonName(String lessonName) {
  8.         this.lessonName = lessonName;
  9.     }
  10.     @Override
  11.     public String toString() {
  12.         return "Lesson{" +
  13.                 "lessonName='" + lessonName + '\'' +
  14.                 '}';
  15.     }
  16. }
复制代码
  1. package com.qcby.spring.dimap;
  2. import java.util.List;
  3. import java.util.Map;
  4. public class Student {
  5.     private List<Lesson> lessonList;
  6.     private Map<String,Teacher> teacherMap;
  7.     private String sid;
  8.     private String sname;
  9.     public void run(){
  10.         System.out.println("学生编号:"+sid+"学生名称:"+sname);
  11.         System.out.println(teacherMap);
  12.         System.out.println(lessonList);
  13.     }
  14.     public List<Lesson> getLessonList() {
  15.         return lessonList;
  16.     }
  17.     public void setLessonList(List<Lesson> lessonList) {
  18.         this.lessonList = lessonList;
  19.     }
  20.     public Map<String, Teacher> getTeacherMap() {
  21.         return teacherMap;
  22.     }
  23.     public void setTeacherMap(Map<String, Teacher> teacherMap) {
  24.         this.teacherMap = teacherMap;
  25.     }
  26.     public String getSid() {
  27.         return sid;
  28.     }
  29.     public void setSid(String sid) {
  30.         this.sid = sid;
  31.     }
  32.     public String getSname() {
  33.         return sname;
  34.     }
  35.     public void setSname(String sname) {
  36.         this.sname = sname;
  37.     }
  38. }
复制代码
使用util:list、util:map标签必须引入相应的命名空间  
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xmlns:util="http://www.springframework.org/schema/util"
  5.        xsi:schemaLocation="http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  6.     <!--
  7.       1.创建三个对象
  8.       2.注入普通类型属性
  9.       3.使用util:类型定义
  10.       4.在学生bean引入util:类型定义bean,完成list、map类型属性注入
  11.     -->
  12.     <bean id="lessonone" class="com.qcby.spring.dimap.Lesson">
  13.         <property name="lessonName" value="java"></property>
  14.     </bean>
  15.     <bean id="lessontwo" class="com.qcby.spring.dimap.Lesson">
  16.         <property name="lessonName" value="python"></property>
  17.     </bean>
  18.     <bean id="teacherone" class="com.qcby.spring.dimap.Teacher">
  19.         <property name="teacherId" value="100"></property>
  20.         <property name="teacherName" value="讲师1"></property>
  21.     </bean>
  22.     <bean id="teachertwo" class="com.qcby.spring.dimap.Teacher">
  23.         <property name="teacherId" value="200"></property>
  24.         <property name="teacherName" value="讲师2"></property>
  25.     </bean>
  26.     <bean id="student" class="com.qcby.spring.dimap.Student">
  27.         <property name="sid" value="001"></property>
  28.         <property name="sname" value="lucy"></property>
  29.         <!--注入list、map类型属性-->
  30.         <property name="lessonList" ref="lessonList"></property>
  31.         <property name="teacherMap" ref="teacherMap"></property>
  32.     </bean>
  33.     <util:list id="lessonList">
  34.         <ref bean="lessonone"></ref>
  35.         <ref bean="lessontwo"></ref>
  36.     </util:list>
  37.     <util:map id="teacherMap">
  38.         <entry>
  39.             <key>
  40.                 <value>1001</value>
  41.             </key>
  42.             <ref bean="teacherone"></ref>
  43.         </entry>
  44.         <entry>
  45.             <key>
  46.                 <value>1002</value>
  47.             </key>
  48.             <ref bean="teachertwo"></ref>
  49.         </entry>
  50.     </util:map>
  51. </beans>
复制代码

p命名空间

引入p命名空间:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xmlns:util="http://www.springframework.org/schema/util"
  5.        xmlns:p="http://www.springframework.org/schema/p"
  6.        xsi:schemaLocation="http://www.springframework.org/schema/util
  7.        http://www.springframework.org/schema/util/spring-util.xsd
  8.        http://www.springframework.org/schema/beans
  9.        http://www.springframework.org/schema/beans/spring-beans.xsd">
复制代码
引入p命名空间后,可以通过以下方式为bean的各个属性赋值:
  1. <bean id="studentSix" class="com.qcby.spring6.bean.Student"
  2.     p:id="1006" p:name="小明" p:clazz-ref="clazzOne" p:teacherMap-ref="teacherMap"></bean>
复制代码
引入外下属性文件

1.加入依赖
  1. <!-- MySQL驱动 -->
  2. <dependency>
  3.     <groupId>mysql</groupId>
  4.     <artifactId>mysql-connector-java</artifactId>
  5.     <version>8.0.30</version>
  6. </dependency>
  7. <!-- 数据源 -->
  8. <dependency>
  9.     <groupId>com.alibaba</groupId>
  10.     <artifactId>druid</artifactId>
  11.     <version>1.2.15</version>
  12. </dependency>
复制代码
2.创建外下属性文件
  1. jdbc.user=root
  2. jdbc.password=123456
  3. jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
  4. jdbc.driver=com.mysql.cj.jdbc.Driver
复制代码
3.配置bean
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xmlns:context="http://www.springframework.org/schema/context"
  5.        xsi:schemaLocation="http://www.springframework.org/schema/beans
  6.        http://www.springframework.org/schema/beans/spring-beans.xsd
  7.        http://www.springframework.org/schema/context
  8.        http://www.springframework.org/schema/context/spring-context.xsd">
  9.     <!--引入外部属性文件-->
  10.     <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
  11.     <!--完成数据库信息注入-->
  12.     <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
  13.         <property name="url" value="${jdbc.url}"/>
  14.         <property name="driverClassName" value="${jdbc.driver}"/>
  15.         <property name="username" value="${jdbc.user}"/>
  16.         <property name="password" value="${jdbc.password}"/>
  17.     </bean>
  18. </beans>
复制代码
4.测试
  1. package com.qcby.spring;
  2. import com.alibaba.druid.pool.DruidDataSource;
  3. import org.junit.Test;
  4. import org.springframework.context.ApplicationContext;
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;
  6. public class TestJdbc {
  7.     @Test
  8.     public void demo(){
  9.         ApplicationContext context = new ClassPathXmlApplicationContext("bean_jdbc.xml");
  10.         DruidDataSource dataSource = context.getBean(DruidDataSource.class);
  11.         System.out.println(dataSource.getUrl());
  12.     }
  13. }
复制代码

bean的作用域

在Spring中可以通过配置bean标签的scope属性来指定bean的作用域范围,各取值含义到场下表:
取值含义创建对象的机遇singleton(默认)在IOC容器中,这个bean的对象始终为单实例IOC容器初始化时prototype这个bean在IOC容器中有多个实例获取bean时 如果是在WebApplicationContext环境下还会有另外几个作用域(但不常用):
取值含义request在一个哀求范围内有用session在一个会话范围内有用



演示:
1.创建Orders类
2.测试单实例:地址相同
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.     <!--通过scope属性配置单实例、多实例-->
  6.     <bean id="orders" class="com.qcby.spring.scope.Orders"
  7.     scope="singleton"></bean>
  8. </beans>
复制代码
  1. package com.qcby.spring;
  2. import com.qcby.spring.scope.Orders;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5. public class TestOrders {
  6.     public static void main(String[] args) {
  7.         ApplicationContext context =
  8.                 new ClassPathXmlApplicationContext("bean_scope.xml");
  9.         Orders orders = context.getBean("orders", Orders.class);
  10.         System.out.println(orders);
  11.         Orders orders1 = context.getBean("orders", Orders.class);
  12.         System.out.println(orders1);
  13.     }
  14. }
复制代码

3.测试多实例:地址不同
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.     <!--通过scope属性配置单实例、多实例-->
  6.     <bean id="orders" class="com.qcby.spring.scope.Orders"
  7.     scope="prototype"></bean>
  8. </beans>
复制代码

bean的生命周期

1.bean对象创建(调用无参构造器)
2.给bean对象设置相关属性
3.bean的后置处理器(初始化之前)
4.bean对象初始化(需在配置bean时指定初始化方法)
5.bean的后置处理器(初始化之后)
6.bean对象就绪可以使用
7.bean对象销毁(需在配置bean时指定销毁方法)
8.IoC容器关闭
演示:
  1. package com.qcby.spring.life;
  2. public class User {
  3.     private String name;
  4.     //无参构造
  5.     public User() {
  6.         System.out.println("1.bean对象创建,调用无参构造");
  7.     }
  8.     public String getName() {
  9.         return name;
  10.     }
  11.     public void setName(String name) {
  12.         System.out.println("2.给bean设置属性值");
  13.         this.name = name;
  14.     }
  15.     //初始化的方法
  16.     public void  initMethod(){
  17.         System.out.println("4.bean对象初始化,调用指定的初始化的方法");
  18.     }
  19.     //销毁的方法
  20.     public void destroyMethod(){
  21.         System.out.println("7.bean对象销毁,调用指定的销毁的方法");
  22.     }
  23. }
复制代码
bean的后置处理器会在生命周期的初始化前后添加额外的操作,需要实现BeanPostProcessor接口,且配置到IOC容器中,需要留意的是,bean后置处理器不是单独针对某一个bean生效,而是针对IOC容器中全部bean都会执行  
  1. package com.qcby.spring.life;
  2. import org.springframework.beans.BeansException;
  3. import org.springframework.beans.factory.config.BeanPostProcessor;
  4. import org.springframework.lang.Nullable;
  5. public class MyBeanPost implements BeanPostProcessor {
  6.     @Override
  7.     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  8.         System.out.println("3.bean后置处理器,初始化之前执行");
  9.         System.out.println(beanName+"::"+bean);
  10.         return bean;
  11.     }
  12.     @Override
  13.     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  14.         System.out.println("5.bean后置处理器,初始化之后执行");
  15.         System.out.println(beanName+"::"+bean);
  16.         return bean;
  17.     }
  18. }
复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.     <bean id="user" class="com.qcby.spring.life.User"
  6.     scope="singleton" init-method="initMethod" destroy-method="destroyMethod">
  7.         <property name="name" value="lucy"></property>
  8.     </bean>
  9.     <!-- bean的后置处理器要放入IOC容器才能生效 -->
  10.     <bean id="myBeanProcessor" class="com.qcby.spring.life.MyBeanPost"/>
  11. </beans>
复制代码
  1. package com.qcby.spring;
  2. import com.qcby.spring.life.User;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5. public class TestUser {
  6.     public static void main(String[] args) {
  7.         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean_life.xml");
  8.         User user = context.getBean("user", User.class);
  9.         System.out.println("6.bean对象创建完成,可以使用");
  10.         System.out.println(user);
  11.         context.close();
  12.     }
  13. }
复制代码

FactoryBean

FactoryBean是Spring提供的一种整合第三方框架的常用机制。和普通的bean不同,配置一个FactoryBean范例的bean,在获取bean的时候得到的并不是class属性中配置的这个类的对象,而是getObject()方法的返回值。通过这种机制,Spring可以帮我们把复杂组件创建的具体过程和繁琐细节都屏蔽起来,只把最简便的使用界面展示给我们,未来我们整合Mybatis时,Spring就是通过FactoryBean机制来帮我们创建SqlSessionFactory对象的
演示:
  1. package com.qcby.spring.factorybean;
  2. import org.springframework.beans.factory.FactoryBean;
  3. public class MyFactoryBean implements FactoryBean<User> {
  4.     @Override
  5.     public User getObject() throws Exception {
  6.         return new User();
  7.     }
  8.     @Override
  9.     public Class<?> getObjectType() {
  10.         return User.class;
  11.     }
  12. }
复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.     <bean id="user" class="com.qcby.spring.factorybean.MyFactoryBean"></bean>
  6. </beans>
复制代码
  1. package com.qcby.spring;
  2. import com.qcby.spring.factorybean.User;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5. public class TestUser1 {
  6.     public static void main(String[] args) {
  7.         ApplicationContext context =
  8.                 new ClassPathXmlApplicationContext("bean_factorybean.xml");
  9.         User user = (User) context.getBean("user");
  10.         System.out.println(user);
  11.     }
  12. }
复制代码

基于xml自动装配

自动装配:根据指定的计谋,在IOC容器中匹配某一个bean,自动为指定的bean中所依赖的类范例或接口范例属性赋值

使用bean标签的autowire属性设置自动装配结果
1.自动装配方式:byType(找的是class)
byType:根据范例匹配IOC容器中的某个兼容范例的bean,为属性自动赋值
若在IOC中,没有任何一个兼容范例的bean可以或许为属性赋值,则该属性不装配,即值为默认值null
若在IOC中,有多个兼容范例的bean可以或许为属性赋值,则抛出异常NoUniqueBeanDefinitionException
2.自动装配方式:byName(找的是id)
byName:将自动装配的属性的属性名,作为bean的id在IOC容器中匹配相对应的bean进行赋值
byType演示:
  1. package com.qcby.spring.auto.controller;
  2. import com.qcby.spring.auto.service.UserService;
  3. import com.qcby.spring.auto.service.UserServiceImpl;
  4. public class UserController {
  5.     private UserService userService;
  6.     public void setUserService(UserService userService) {
  7.         this.userService = userService;
  8.     }
  9.     public void addUser(){
  10.         System.out.println("controller中的方法执行了");
  11.         //调用service的方法
  12.         userService.addUserService();
  13.     }
  14. }
复制代码
  1. package com.qcby.spring.auto.service;
  2. public interface UserService {
  3.     public void addUserService();
  4. }
复制代码
  1. package com.qcby.spring.auto.service;
  2. import com.qcby.spring.auto.dao.UserDao;
  3. import com.qcby.spring.auto.dao.UserDaoImpl;
  4. public class UserServiceImpl implements UserService{
  5.     private UserDao userDao;
  6.     public void setUserDao(UserDao userDao) {
  7.         this.userDao = userDao;
  8.     }
  9.     @Override
  10.     public void addUserService() {
  11.         System.out.println("userService中的方法执行了");
  12.         //调用dao中的方法
  13.         userDao.addUserDao();
  14.     }
  15. }
复制代码
  1. package com.qcby.spring.auto.dao;
  2. public interface UserDao {
  3.     public void addUserDao();
  4. }
复制代码
  1. package com.qcby.spring.auto.dao;
  2. public class UserDaoImpl implements UserDao{
  3.     @Override
  4.     public void addUserDao() {
  5.         System.out.println("userDao中的方法执行了");
  6.     }
  7. }
复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.     <bean id="userController" class="com.qcby.spring.auto.controller.UserController"
  6.           autowire="byType">
  7.     </bean>
  8.     <bean id="userService" class="com.qcby.spring.auto.service.UserServiceImpl"
  9.           autowire="byType">
  10.     </bean>
  11.     <bean id="userDao" class="com.qcby.spring.auto.dao.UserDaoImpl"></bean>
  12. </beans>
复制代码
  1. package com.qcby.spring;
  2. import com.qcby.spring.auto.controller.UserController;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5. public class TestUser1 {
  6.     public static void main(String[] args) {
  7.         ApplicationContext context =
  8.                 new ClassPathXmlApplicationContext("bean_auto.xml");
  9.         UserController controller = context.getBean("userController", UserController.class);
  10.         controller.addUser();
  11.     }
  12. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

南飓风

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表