目次
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创建对象的过程中,将对象依赖属性通过配置进行注入
依赖注入常见的实现方式包括两种:
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
- package com.qcby.spring;
- public class User {
- private String name;
- private Integer age;
- public void run(){
- System.out.println("run...");
- }
- }
复制代码 获取bean
①方式一:根据id获取
由于 id 属性指定了 bean 的唯一标识,以是根据 bean 标签的 id 属性可以精确获取到一个组件对象(入门案例)
bean.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">
- <!--user对象创建-->
- <bean id="user" class="com.qcby.spring.User"></bean>
- </beans>
复制代码 测试类:
- package com.qcby.spring;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class TestUser {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
- //根据id获取bean
- User user = (User) context.getBean("user");
- System.out.println("根据id获取bean:"+user);
- }
- }
复制代码
②方式二:根据范例获取
- package com.qcby.spring;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class TestUser {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
- //根据id获取bean
- // User user = (User) context.getBean("user");
- // System.out.println("根据id获取bean:"+user);
- //根据类型获取bean
- User user = context.getBean(User.class);
- System.out.println("根据类型获取bean"+user);
- }
- }
复制代码
当根据范例获取bean时,要求IOC容器中指定范例的bean有且只能有一个
若配置多个,会抛出异常:org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type
③方式三:根据id和范例
- package com.qcby.spring;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class TestUser {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
- //根据id获取bean
- // User user = (User) context.getBean("user");
- // System.out.println("根据id获取bean:"+user);
- //根据类型获取bean
- // User user = context.getBean(User.class);
- // System.out.println("根据类型获取bean"+user);
- //根据id和类型获取bean
- User user = context.getBean("user", User.class);
- System.out.println("根据id和类型获取bean:"+user);
- }
- }
复制代码
扩展:
如果组件类实现了接口,根据接口范例可以获取 bean 吗?
- package com.qcby.spring;
- public interface UserDao {
- public void run();
- }
复制代码- package com.qcby.spring;
- public class UserDaoImpl implements UserDao{
- @Override
- public void run() {
- System.out.println("run...");
- }
- }
复制代码- <!--一个接口获取类过程-->
- <bean id="userDaoImpl" class="com.qcby.spring.bean.UserDaoImpl.UserDaoImpl"></bean>
复制代码- package com.qcby.spring;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class TestUserDao {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
- //根据类型获取接口对应bean
- UserDao userDao = context.getBean(UserDao.class);
- System.out.println(userDao);
- userDao.run();
- }
- }
复制代码
如果一个接口有多个实现类,这些实现类都配置了 bean,根据接口范例可以获取 bean 吗?
依赖注入
setter注入
第一步:创建类,天生属性set方法
第二步:在spring配置文件配置
- package com.qcby.spring.di;
- public class Book {
- private String bname;
- private String author;
- //无参构造
- public Book() {
- }
- //有参构造
- public Book(String bname, String author) {
- this.bname = bname;
- this.author = author;
- }
- //生成get和set方法
- public void setBname(String bname) {
- this.bname = bname;
- }
- public void setAuthor(String author) {
- this.author = author;
- }
- public String getBname() {
- return bname;
- }
- public String getAuthor() {
- return author;
- }
- @Override
- public String toString() {
- return "Book{" +
- "bname='" + bname + '\'' +
- ", author='" + author + '\'' +
- '}';
- }
- }
复制代码- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"
- 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">
- <!--set方法注入-->
- <!-- property标签:通过组件类的setXxx()方法给组件对象设置属性 -->
- <!-- name属性:指定属性名(这个属性名是getXxx()、setXxx()方法定义的,和成员变量无关) -->
- <!-- value属性:指定属性值 -->
- <bean id="book" class="com.qcby.spring.di.Book">
- <property name="bname" value="前端开发"></property>
- <property name="author" value="张三"></property>
- </bean>
- </beans>
复制代码- package com.qcby.spring;
- import com.qcby.spring.di.Book;
- import org.junit.Test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class TestBook {
- @Test
- public void testSetter(){
- ApplicationContext context = new ClassPathXmlApplicationContext("bean_di.xml");
- Book book = context.getBean("book", Book.class);
- System.out.println(book);
- }
- }
复制代码
构造器注入
第一步:创建类,定义属性,天生有参构造方法
第二步:在spring配置文件配置
- <!--构造器注入-->
- <bean id="bookCon" class="com.qcby.spring.di.Book">
- <constructor-arg name="bname" value="java开发"></constructor-arg>
- <constructor-arg name="author" value="李四"></constructor-arg>
- </bean>
复制代码 留意:
constructor-arg标签还有两个属性可以进一步描述构造器参数:
- index属性:指定参数所在位置的索引(从0开始)
- name属性:指定参数名
- @Test
- public void testCon(){
- ApplicationContext context = new ClassPathXmlApplicationContext("bean_di.xml");
- Book book = context.getBean("bookCon", Book.class);
- System.out.println(book);
- }
复制代码
特殊值处理
字面量赋值
什么是字面量?
int a = 10;
声明一个变量a,初始化为10,此时a不代表字母a,而是作为一个变量的名字。当引用a的时候,实际上拿到的值是10。
而如果a是带引号的:'a',那么它如今不是一个变量,它就是代表a这个字母本身,这就是字面量。以是字面量没有引申含义,就是我们看到的这个数据本身
- <!-- 使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量 -->
- <property name="name" value="张三"/>
复制代码 null值
- <property name="name">
- <null />
- </property>
复制代码 留意:以下写法为name所赋的值是字符串null
- <property name="name" value="null"></property>
复制代码 xml实体
- <!-- 小于号在XML文档中用来定义标签的开始,不能随便使用 -->
- <!-- 解决方案一:使用XML实体来代替 -->
- <property name="expression" value="a < b"/>
复制代码 CDATA节
- <property name="expression">
- <!-- 解决方案二:使用CDATA节 -->
- <!-- CDATA中的C代表Character,是文本、字符的含义,CDATA就表示纯文本数据 -->
- <!-- XML解析器看到CDATA节就知道这里是纯文本,就不会当作XML标签或属性来解析 -->
- <!-- 所以CDATA节中写什么符号都随意 -->
- <value><![CDATA[a < b]]></value>
- </property>
复制代码 特殊范例属性注入
对象范例属性注入
- package com.qcby.spring.ditest;
- //部门类
- public class Dept {
- private String dname;
- public void info(){
- System.out.println("部门名称:"+dname);
- }
- public void setDname(String dname) {
- this.dname = dname;
- }
- public String getDname() {
- return dname;
- }
- }
复制代码- package com.qcby.spring.ditest;
- //员工类
- public class Emp {
- //对象类型属性:员工属于某个部门
- private Dept dept;
- private String ename;
- private Integer age;
- public void work(){
- System.out.println(ename+"emp work..."+age);
- dept.info();
- }
- public Dept getDept() {
- return dept;
- }
- public void setDept(Dept dept) {
- this.dept = dept;
- }
- public String getEname() {
- return ename;
- }
- public void setEname(String ename) {
- this.ename = ename;
- }
- public Integer getAge() {
- return age;
- }
- public void setAge(Integer age) {
- this.age = age;
- }
- }
复制代码 方式一:引用外部bean
使用ref属性
- <!--方式一:引入外部bean
- 1.创建两个类对象:dept emp
- 2.在emp的bean标签里,使用property引入dept的bean
- -->
- <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="50"></property>
- <!--对象属性注入
- ref属性:引用IOC容器中某个bean的id,将所对应的bean为属性赋值-->
- <property name="dept" ref="dept"></property>
- </bean>
复制代码
方式二:内部bean
- <!--方式二:内部bean-->
- <!-- 在一个bean中再声明一个bean就是内部bean -->
- <!-- 内部bean只能用于给属性赋值,不能在外部通过IOC容器获取,因此可以省略id属性 -->
- <bean id="emp2" class="com.qcby.spring.ditest.Emp">
- <!--普通属性注入-->
- <property name="ename" value="mary"></property>
- <property name="age" value="20"></property>
- <!--对象属性注入-->
- <property name="dept">
- <bean id="dept2" class="com.qcby.spring.ditest.Dept">
- <property name="dname" value="财务部"></property>
- </bean>
- </property>
- </bean>
复制代码
方式三:级联属性赋值
- <!--方式三:级联赋值-->
- <bean id="dept3" class="com.qcby.spring.ditest.Dept">
- <property name="dname" value="研发部"></property>
- </bean>
- <bean id="emp3" class="com.qcby.spring.ditest.Emp">
- <!--普通属性注入-->
- <property name="ename" value="tom"></property>
- <property name="age" value="30"></property>
- <!--对象属性注入-->
- <property name="dept" ref="dept3"></property>
- <property name="dept.dname" value="测试部"></property>
- </bean>
复制代码
数组范例属性注入
员工类:
- //爱好
- private String[] loves;
- public String[] getLoves() {
- return loves;
- }
- public void setLoves(String[] loves) {
- this.loves = loves;
- }
- public void work(){
- System.out.println(ename+"emp work..."+age);
- dept.info();
- System.out.println(Arrays.toString(loves));
- }
复制代码- <!--数组类型属性-->
- <property name="loves">
- <array>
- <value>吃饭</value>
- <value>睡觉</value>
- <value>看电影</value>
- </array>
- </property>
复制代码 完整的配置文件:
- <?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> <!--数组类型属性-->
- <property name="loves">
- <array>
- <value>吃饭</value>
- <value>睡觉</value>
- <value>看电影</value>
- </array>
- </property> </bean></beans>
复制代码
集合范例属性注入
list、set集合范例
Dept类:
- private List<Emp> empList;
-
- public void info(){
- System.out.println("部门名称:"+dname);
- for (Emp emp : empList) {
- System.out.println(emp.getEname());
- }
- }
- public List<Emp> getEmpList() {
- return empList;
- }
- public void setEmpList(List<Emp> empList) {
- this.empList = empList;
- }
- }
复制代码- <?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="empone" class="com.qcby.spring.ditest.Emp">
- <property name="ename" value="lucy"></property>
- <property name="age" value="20"></property>
- </bean>
- <bean id="emptwo" class="com.qcby.spring.ditest.Emp">
- <property name="ename" value="mary"></property>
- <property name="age" value="30"></property>
- </bean>
- <bean id="dept" class="com.qcby.spring.ditest.Dept">
- <property name="dname" value="技术部"></property>
- <property name="empList">
- <list>
- <ref bean="empone"></ref>
- <ref bean="emptwo"></ref>
- </list>
- </property>
- </bean>
- </beans>
复制代码 若为Set集合范例属性赋值,只需要将其中的list标签改为set标签即可
map集合范例
Student和Teacher类:
- package com.qcby.spring.dimap;
- import java.util.Map;
- public class Student {
- private Map<String,Teacher> teacherMap;
- private String sid;
- private String sname;
- public void run(){
- System.out.println("学生编号:"+sid+"学生名称:"+sname);
- System.out.println(teacherMap);
- }
- public Map<String, Teacher> getTeacherMap() {
- return teacherMap;
- }
- public void setTeacherMap(Map<String, Teacher> teacherMap) {
- this.teacherMap = teacherMap;
- }
- public String getSid() {
- return sid;
- }
- public void setSid(String sid) {
- this.sid = sid;
- }
- public String getSname() {
- return sname;
- }
- public void setSname(String sname) {
- this.sname = sname;
- }
- }
复制代码- package com.qcby.spring.dimap;
- public class Teacher {
- private String teacherId;
- private String teacherName;
- public String getTeacherId() {
- return teacherId;
- }
- public void setTeacherId(String teacherId) {
- this.teacherId = teacherId;
- }
- public String getTeacherName() {
- return teacherName;
- }
- public void setTeacherName(String teacherName) {
- this.teacherName = teacherName;
- }
- @Override
- public String toString() {
- return "Teacher{" +
- "teacherId='" + teacherId + '\'' +
- ", teacherName='" + teacherName + '\'' +
- '}';
- }
- }
复制代码- <?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">
- <!--
- 1.创建两个对象
- 2.注入普通类型属性
- 3.在学生bean注入map集合类型属性
- -->
- <bean id="teacherone" class="com.qcby.spring.dimap.Teacher">
- <!--注入普通类型属性-->
- <property name="teacherId" value="100"></property>
- <property name="teacherName" value="讲师1"></property>
- </bean>
- <bean id="teachertwo" class="com.qcby.spring.dimap.Teacher">
- <!--注入普通类型属性-->
- <property name="teacherId" value="200"></property>
- <property name="teacherName" value="讲师2"></property>
- </bean>
- <bean id="student" class="com.qcby.spring.dimap.Student">
- <!--注入普通类型属性-->
- <property name="sid" value="2000"></property>
- <property name="sname" value="李四"></property>
- <!--在学生bean注入map集合类型属性-->
- <property name="teacherMap">
- <map>
- <entry>
- <!--key-->
- <key>
- <value>1</value>
- </key>
- <!--value为对象-->
- <ref bean="teacherone"></ref>
- </entry>
- <entry>
- <!--key-->
- <key>
- <value>2</value>
- </key>
- <!--value为对象-->
- <ref bean="teachertwo"></ref>
- </entry>
- </map>
- </property>
- </bean>
- </beans>
复制代码
引用集合范例
Lesson类:
- package com.qcby.spring.dimap;
- public class Lesson {
- private String lessonName;
- public String getLessonName() {
- return lessonName;
- }
- public void setLessonName(String lessonName) {
- this.lessonName = lessonName;
- }
- @Override
- public String toString() {
- return "Lesson{" +
- "lessonName='" + lessonName + '\'' +
- '}';
- }
- }
复制代码- package com.qcby.spring.dimap;
- import java.util.List;
- import java.util.Map;
- public class Student {
- private List<Lesson> lessonList;
- private Map<String,Teacher> teacherMap;
- private String sid;
- private String sname;
- public void run(){
- System.out.println("学生编号:"+sid+"学生名称:"+sname);
- System.out.println(teacherMap);
- System.out.println(lessonList);
- }
- public List<Lesson> getLessonList() {
- return lessonList;
- }
- public void setLessonList(List<Lesson> lessonList) {
- this.lessonList = lessonList;
- }
- public Map<String, Teacher> getTeacherMap() {
- return teacherMap;
- }
- public void setTeacherMap(Map<String, Teacher> teacherMap) {
- this.teacherMap = teacherMap;
- }
- public String getSid() {
- return sid;
- }
- public void setSid(String sid) {
- this.sid = sid;
- }
- public String getSname() {
- return sname;
- }
- public void setSname(String sname) {
- this.sname = sname;
- }
- }
复制代码 使用util:list、util:map标签必须引入相应的命名空间
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:util="http://www.springframework.org/schema/util"
- 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">
- <!--
- 1.创建三个对象
- 2.注入普通类型属性
- 3.使用util:类型定义
- 4.在学生bean引入util:类型定义bean,完成list、map类型属性注入
- -->
- <bean id="lessonone" class="com.qcby.spring.dimap.Lesson">
- <property name="lessonName" value="java"></property>
- </bean>
- <bean id="lessontwo" class="com.qcby.spring.dimap.Lesson">
- <property name="lessonName" value="python"></property>
- </bean>
- <bean id="teacherone" class="com.qcby.spring.dimap.Teacher">
- <property name="teacherId" value="100"></property>
- <property name="teacherName" value="讲师1"></property>
- </bean>
- <bean id="teachertwo" class="com.qcby.spring.dimap.Teacher">
- <property name="teacherId" value="200"></property>
- <property name="teacherName" value="讲师2"></property>
- </bean>
- <bean id="student" class="com.qcby.spring.dimap.Student">
- <property name="sid" value="001"></property>
- <property name="sname" value="lucy"></property>
- <!--注入list、map类型属性-->
- <property name="lessonList" ref="lessonList"></property>
- <property name="teacherMap" ref="teacherMap"></property>
- </bean>
- <util:list id="lessonList">
- <ref bean="lessonone"></ref>
- <ref bean="lessontwo"></ref>
- </util:list>
- <util:map id="teacherMap">
- <entry>
- <key>
- <value>1001</value>
- </key>
- <ref bean="teacherone"></ref>
- </entry>
- <entry>
- <key>
- <value>1002</value>
- </key>
- <ref bean="teachertwo"></ref>
- </entry>
- </util:map>
- </beans>
复制代码
p命名空间
引入p命名空间:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:util="http://www.springframework.org/schema/util"
- xmlns:p="http://www.springframework.org/schema/p"
- 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">
复制代码 引入p命名空间后,可以通过以下方式为bean的各个属性赋值:
- <bean id="studentSix" class="com.qcby.spring6.bean.Student"
- p:id="1006" p:name="小明" p:clazz-ref="clazzOne" p:teacherMap-ref="teacherMap"></bean>
复制代码 引入外下属性文件
1.加入依赖
- <!-- MySQL驱动 -->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>8.0.30</version>
- </dependency>
- <!-- 数据源 -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid</artifactId>
- <version>1.2.15</version>
- </dependency>
复制代码 2.创建外下属性文件
- jdbc.user=root
- jdbc.password=123456
- jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
- jdbc.driver=com.mysql.cj.jdbc.Driver
复制代码 3.配置bean
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd">
- <!--引入外部属性文件-->
- <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
- <!--完成数据库信息注入-->
- <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
- <property name="url" value="${jdbc.url}"/>
- <property name="driverClassName" value="${jdbc.driver}"/>
- <property name="username" value="${jdbc.user}"/>
- <property name="password" value="${jdbc.password}"/>
- </bean>
- </beans>
复制代码 4.测试
- package com.qcby.spring;
- import com.alibaba.druid.pool.DruidDataSource;
- import org.junit.Test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class TestJdbc {
- @Test
- public void demo(){
- ApplicationContext context = new ClassPathXmlApplicationContext("bean_jdbc.xml");
- DruidDataSource dataSource = context.getBean(DruidDataSource.class);
- System.out.println(dataSource.getUrl());
- }
- }
复制代码
bean的作用域
在Spring中可以通过配置bean标签的scope属性来指定bean的作用域范围,各取值含义到场下表:
取值含义创建对象的机遇singleton(默认)在IOC容器中,这个bean的对象始终为单实例IOC容器初始化时prototype这个bean在IOC容器中有多个实例获取bean时 如果是在WebApplicationContext环境下还会有另外几个作用域(但不常用):
取值含义request在一个哀求范围内有用session在一个会话范围内有用
演示:
1.创建Orders类
2.测试单实例:地址相同
- <?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">
- <!--通过scope属性配置单实例、多实例-->
- <bean id="orders" class="com.qcby.spring.scope.Orders"
- scope="singleton"></bean>
- </beans>
复制代码- package com.qcby.spring;
- import com.qcby.spring.scope.Orders;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class TestOrders {
- public static void main(String[] args) {
- ApplicationContext context =
- new ClassPathXmlApplicationContext("bean_scope.xml");
- Orders orders = context.getBean("orders", Orders.class);
- System.out.println(orders);
- Orders orders1 = context.getBean("orders", Orders.class);
- System.out.println(orders1);
- }
- }
复制代码
3.测试多实例:地址不同
- <?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">
- <!--通过scope属性配置单实例、多实例-->
- <bean id="orders" class="com.qcby.spring.scope.Orders"
- scope="prototype"></bean>
- </beans>
复制代码
bean的生命周期
1.bean对象创建(调用无参构造器)
2.给bean对象设置相关属性
3.bean的后置处理器(初始化之前)
4.bean对象初始化(需在配置bean时指定初始化方法)
5.bean的后置处理器(初始化之后)
6.bean对象就绪可以使用
7.bean对象销毁(需在配置bean时指定销毁方法)
8.IoC容器关闭
演示:
- package com.qcby.spring.life;
- public class User {
- private String name;
- //无参构造
- public User() {
- System.out.println("1.bean对象创建,调用无参构造");
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- System.out.println("2.给bean设置属性值");
- this.name = name;
- }
- //初始化的方法
- public void initMethod(){
- System.out.println("4.bean对象初始化,调用指定的初始化的方法");
- }
- //销毁的方法
- public void destroyMethod(){
- System.out.println("7.bean对象销毁,调用指定的销毁的方法");
- }
- }
复制代码 bean的后置处理器会在生命周期的初始化前后添加额外的操作,需要实现BeanPostProcessor接口,且配置到IOC容器中,需要留意的是,bean后置处理器不是单独针对某一个bean生效,而是针对IOC容器中全部bean都会执行
- package com.qcby.spring.life;
- import org.springframework.beans.BeansException;
- import org.springframework.beans.factory.config.BeanPostProcessor;
- import org.springframework.lang.Nullable;
- public class MyBeanPost implements BeanPostProcessor {
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- System.out.println("3.bean后置处理器,初始化之前执行");
- System.out.println(beanName+"::"+bean);
- return bean;
- }
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- System.out.println("5.bean后置处理器,初始化之后执行");
- System.out.println(beanName+"::"+bean);
- return bean;
- }
- }
复制代码- <?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="user" class="com.qcby.spring.life.User"
- scope="singleton" init-method="initMethod" destroy-method="destroyMethod">
- <property name="name" value="lucy"></property>
- </bean>
- <!-- bean的后置处理器要放入IOC容器才能生效 -->
- <bean id="myBeanProcessor" class="com.qcby.spring.life.MyBeanPost"/>
- </beans>
复制代码- package com.qcby.spring;
- import com.qcby.spring.life.User;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class TestUser {
- public static void main(String[] args) {
- ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean_life.xml");
- User user = context.getBean("user", User.class);
- System.out.println("6.bean对象创建完成,可以使用");
- System.out.println(user);
- context.close();
- }
- }
复制代码
FactoryBean
FactoryBean是Spring提供的一种整合第三方框架的常用机制。和普通的bean不同,配置一个FactoryBean范例的bean,在获取bean的时候得到的并不是class属性中配置的这个类的对象,而是getObject()方法的返回值。通过这种机制,Spring可以帮我们把复杂组件创建的具体过程和繁琐细节都屏蔽起来,只把最简便的使用界面展示给我们,未来我们整合Mybatis时,Spring就是通过FactoryBean机制来帮我们创建SqlSessionFactory对象的
演示:
- package com.qcby.spring.factorybean;
- import org.springframework.beans.factory.FactoryBean;
- public class MyFactoryBean implements FactoryBean<User> {
- @Override
- public User getObject() throws Exception {
- return new User();
- }
- @Override
- public Class<?> getObjectType() {
- return User.class;
- }
- }
复制代码- <?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="user" class="com.qcby.spring.factorybean.MyFactoryBean"></bean>
- </beans>
复制代码- package com.qcby.spring;
- import com.qcby.spring.factorybean.User;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class TestUser1 {
- public static void main(String[] args) {
- ApplicationContext context =
- new ClassPathXmlApplicationContext("bean_factorybean.xml");
- User user = (User) context.getBean("user");
- System.out.println(user);
- }
- }
复制代码
基于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演示:
- package com.qcby.spring.auto.controller;
- import com.qcby.spring.auto.service.UserService;
- import com.qcby.spring.auto.service.UserServiceImpl;
- public class UserController {
- private UserService userService;
- public void setUserService(UserService userService) {
- this.userService = userService;
- }
- public void addUser(){
- System.out.println("controller中的方法执行了");
- //调用service的方法
- userService.addUserService();
- }
- }
复制代码- package com.qcby.spring.auto.service;
- public interface UserService {
- public void addUserService();
- }
复制代码- package com.qcby.spring.auto.service;
- import com.qcby.spring.auto.dao.UserDao;
- import com.qcby.spring.auto.dao.UserDaoImpl;
- public class UserServiceImpl implements UserService{
- private UserDao userDao;
- public void setUserDao(UserDao userDao) {
- this.userDao = userDao;
- }
- @Override
- public void addUserService() {
- System.out.println("userService中的方法执行了");
- //调用dao中的方法
- userDao.addUserDao();
- }
- }
复制代码- package com.qcby.spring.auto.dao;
- public interface UserDao {
- public void addUserDao();
- }
复制代码- package com.qcby.spring.auto.dao;
- public class UserDaoImpl implements UserDao{
- @Override
- public void addUserDao() {
- System.out.println("userDao中的方法执行了");
- }
- }
复制代码- <?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="userController" class="com.qcby.spring.auto.controller.UserController"
- autowire="byType">
- </bean>
- <bean id="userService" class="com.qcby.spring.auto.service.UserServiceImpl"
- autowire="byType">
- </bean>
- <bean id="userDao" class="com.qcby.spring.auto.dao.UserDaoImpl"></bean>
- </beans>
复制代码- package com.qcby.spring;
- import com.qcby.spring.auto.controller.UserController;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class TestUser1 {
- public static void main(String[] args) {
- ApplicationContext context =
- new ClassPathXmlApplicationContext("bean_auto.xml");
- UserController controller = context.getBean("userController", UserController.class);
- controller.addUser();
- }
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |