Spring5自学笔记_Real002(IOC的Bean管理-基于XML文件)

Spring5自学笔记_Real002(IOC的Bean管理-基于XML文件)

IOC容器-Bean管理-XML方式

(1)Bean管理主要值得是两个操作:Spring创建对象,Spring注入属性

(2)Bean管理操作有两个方式(基于XML配置文件的方式 和 注解方式)

1)基于XML配置文件方式实现
例子:创建对象,然后注入属性
在编写完Book类之后,设置配置文件如下:

<?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">

    <!-- 配置Book对象的创建 -->
    <bean id = "User" class = "com.SSMStudy.Spring5.User"></bean>
    <!-- 2、set方法注入属性 -->
    <bean id = "book" class = "com.SSMStudy.Spring5.testDemo.Book">
        <!-- 使用property完成属性的注入
            name:类里面属性的名称
            value:属性的值-->
        <property name="author" value ="余华"></property>
        <property name="name" value="活着"></property>
    </bean>
</beans>

spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象的创建
在bean标签有很多属性,常用的是id属性:唯一标识,和class属性:类的全路径
属性的注入有两种方式,第一种是用set函数,第二种使用有参构造器进行注入
DI:依赖注入,就是注入属性,DI是IOC的具体实现,他就表示依赖注入,或者说是注入属性,但是他必须在对象创建的基础上进行。
a.set函数注入:然后创建利用Spring创建对象,之后用Set的方式及逆行属性的注入

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Book {
    private String name;
    private String author;

    public void setName(String name) {
        this.name = name;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public void print(){
        System.out.println(author +":"+name);
    }

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        Book book = context.getBean("book", Book.class);

        System.out.println(book);
        book.print();
    }
}
输出结果:
com.SSMStudy.Spring5.testDemo.Book@79da8dc5
余华:活着

b.通过有参构造器进行属性的注入
创建类,定义属性,创建属性对应的额有参数的构造方法

package com.SSMStudy.Spring5.testDemo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Order {
    private String name;
    private String address;

    //有参数的构造器
    public Order(String name, String address) {
        this.name = name;
        this.address = address;
    }


    public void print(){
        System.out.println(name+":"+address);
    }

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        Order order = context.getBean("order", Order.class);
        System.out.println(order);
        order.print();
    }
}

配置文件:

<?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">

    <!-- 配置Book对象的创建 -->
    <bean id = "User" class = "com.SSMStudy.Spring5.User"></bean>

    <!-- 2、set方法注入属性 -->
    <bean id="book" class="com.SSMStudy.Spring5.testDemo.Book">
        <!-- 使用property完成属性的注入
            name:类里面属性的名称
            value:属性的值-->
        <property name="author" value ="余华"></property>
        <property name="name" value="活着"></property>
    </bean>

    <!-- 3、有参数的构造器注入属性 -->
    <bean id="order" class="com.SSMStudy.Spring5.testDemo.Order">
        <constructor-arg name="name" value="张三"></constructor-arg>
        <constructor-arg name="address" value="中国"></constructor-arg>
    </bean>
</beans>
输出结果:
com.SSMStudy.Spring5.testDemo.Order@212b5695
张三:中国

XML属性注入的其他区方式:
字面量:就是值得是属性的初始值
1)空值:null

        <constructor-arg name="address">
            <null></null>
        </constructor-arg>
2)特殊符号:< > (1、使用转移符号或者使用CDATA)
        <constructor-arg name="address">
            <value><![CDATA[<><>中国南京<><>]]></value>
        </constructor-arg>

(3)注入属性-注入外部bean

配置文件:

    <!-- 4、注入外部bean(说白了就是在一个类里面调用另一个类) -->
    <bean name="userDaoImp" class="com.SSMStudy.Spring5.OutBeanInsert.UserDaoImp"></bean>
    <bean id="serviceTest" class="com.SSMStudy.Spring5.OutBeanInsert.ServiceTest">
        <property name="userDaoImp" ref="userDaoImp"></property>
    </bean>

创建相应的类:ServiceTest调用UserDao类,并调用UserDao的方法print,UserDaoImp接口被UseDaoImp实现

public interface UserDao {
    void print();
}

public class UserDaoImp implements UserDao{
    @Override
    public void print() {
        System.out.println("UserDao Start......");
    }
}

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ServiceTest {

    private UserDao userDaoImp;

    public void setUserDaoImp(UserDao userDaoImp) {
        this.userDaoImp = userDaoImp;
    }

    public void print(){
        System.out.println("ServiceTest Start......");
        userDaoImp.print();
    }

    @Test
    public void testBean(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        ServiceTest service = context.getBean("serviceTest", ServiceTest.class);
        service.print();
    }
}
输出结果:
ServiceTest Start......
UserDao Start......

(4)注入属性-注入内部bean

配置文件
与外部注入属性的不同点主要在于XML文件的写法

    <!-- 5、内部bean的注入 -->
    <bean id="emp" class="com.SSMStudy.Spring5.InsideBean.Emp">
        <property name="eName" value="Lucy"></property>
        <property name="dept">
            <bean id="dept" class="com.SSMStudy.Spring5.InsideBean.Dept">
                <property name="DName" value="人事部"></property>
            </bean>
        </property>
    </bean>

创建相应的类:部门类、员工类

public class Dept {
    private String dName;

    public void setDName(String dName) {
        this.dName = dName;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "dName='" + dName + '\'' +
                '}';
    }
}
public class Emp {
    private String eName;
    private Dept dept;

    public void seteName(String eName) {
        this.eName = eName;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "eName='" + eName + '\'' +
                ", dept=" + dept +
                '}';
    }
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class InsideBeanTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        Emp emp = context.getBean("emp", Emp.class);
        System.out.println(emp);
    }
}
输出结果:
Emp{eName='Lucy', dept=Dept{dName='人事部'}}

(5)注入属性-级联赋值

级联赋值就是在注入外部类属性的时候将bean标签写在外面,然后在类种用ref引入
(第一种形式)

    <!-- 6、级联赋值 -->
    <bean id="emp" class="com.SSMStudy.Spring5.InsideBean.Emp">
        <property name="eName" value="Lucy"></property>
        <property name="dept" ref="dept"></property>
    </bean>
    <bean id="dept" class="com.SSMStudy.Spring5.InsideBean.Dept">
        <property name="DName" value="人事部"></property>
    </bean>

(第二种形式)(需要在Emp类中生成Dept的Get方法)

    <!-- 7、级联赋值第二种形式 -->
    <bean id="emp" class="com.SSMStudy.Spring5.InsideBean.Emp">
        <property name="eName" value="Lucy"></property>
        <property name="dept" ref="dept"></property>
        <property name="dept.dName" value="人事部"></property>
    </bean>
    <bean id="dept" class="com.SSMStudy.Spring5.InsideBean.Dept"></bean>

(6)XML文件注入集合属性-注入数组

创建类

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Student {
    private String[] strings;
    private List<String> list;
    private Set<String> set;
    private Map<String, String> maps;

    public void setStrings(String[] strings) {
        this.strings = strings;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void setMaps(Map<String, String> maps) {
        this.maps = maps;
    }

    public void test(){
        System.out.println(Arrays.toString(strings));
        System.out.println(list);
        System.out.println(set);
        System.out.println(maps);
    }

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        Student stu = context.getBean("stu", Student.class);

        stu.test();
    }
}

创建配置文件

    <!-- 8、集合属性的注入方式 -->
    <bean id="stu" class="com.SSMStudy.Spring5.CollectionInsert.Student">
        <property name="strings">
            <array>
                <value>张三</value>
                <value>Mary</value>
            </array>
        </property>
        <property name="list">
            <list>
                <value>Jack</value>
                <value>Tom</value>
            </list>
        </property>
        <property name="set">
            <set>
                <value>Smith</value>
                <value>Lucy</value>
            </set>
        </property>
        <property name="maps">
            <map>
                <entry key="Lucy" value="USA"></entry>
                <entry key="Tom" value="Japan"></entry>
            </map>
        </property>
    </bean>

输出结果:
[张三, Mary]
[Jack, Tom]
[Smith, Lucy]
{Lucy=USA, Tom=Japan}

(7)bean管理小结:

Spring中有两种bean管理方式:一个是普通bean管理,另一个使factoryBean管理
两者的区别主要在于:普通Bean管理,在配置文件中定义的Bean类型和返回的类型必须一致,而FactoryBean管理的在配置文件中定义的Bean类型可以和返回类型不一样。
工厂Bean管理:
第一步:创建类,让这个类实现FactoryBean接口
第二步:实现接口里面的方法,在实现的方法中定义
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">


    <bean id="myBean" class="com.SSMStudy.Spring5.FactoryBeanStudy.MyBean"></bean>
</beans>

Java程序:

import com.SSMStudy.Spring5.testDemo.Book;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyBean implements FactoryBean<Book> {
    /**
     * 定义返回的Bean
     * @return 要实例化的对象
     * @throws Exception
     */
    @Override
    public Book getObject() throws Exception {
        Book book = new Book();
        book.setName("三国演义");
        book.setAuthor("罗贯中");
        return book;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        Book book =  context.getBean("myBean", Book.class);
        System.out.println(book);
    }
}

在默认情况下,Bean管理产生的实例是单实例,即获得的所有实例都是同一个,也就是地址是相同的。

(8)如何设置是多实例还是单实例?

在XML配置文件中的Bean标签下有一个属性叫做:scope
将属性设置为singleton或者不写,也就是默认值,那么产生的实例就是单实例,
将属性设置为prototype,则产生的实例是多实例
在这里插入图片描述

(9)Bean的生命周期**从对象创建到对象销毁的过程

(1)通过构造器创建Bean实例(无参构造)
(2)为bean的属性设置值和对其他bean引用(调用set方法)
(3)调用bean的初始化方法(需要进行配置初始化的方法)
(4)bean可以使用了(对象获取到了)
(5)当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)
XML配置文件

    <bean id="myBeanTest" class="com.SSMStudy.Spring5.FactoryBeanStudy.MyBeanTest" init-method="InitMethod" destroy-method="Destroy">
        <property name="name" value="Mary"></property>
        <property name="age" value="21"></property>
    </bean>

Java程序

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyBeanTest {
    private String name;
    private int age;

    public MyBeanTest() {
        System.out.println("一、构造器创建bean实例(无参构造)");
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "MyBeanTest{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public void InitMethod(){
        System.out.println("三、调用bean的初始化方法");
    }

    public void Destroy(){
        System.out.println("五、调用bean的销毁方法");
    }
    @Test
    public void ApplicationContextTest(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        //System.out.println("二、调用set方法,设置了属性值");
        MyBeanTest myBeanTest = context.getBean("myBeanTest", MyBeanTest.class);
        System.out.println("四、获取到了MyBeanTest的对象");
        System.out.println(myBeanTest);
        ((ClassPathXmlApplicationContext)context).close();
    }
}
输出结果:
一、构造器创建bean实例(无参构造)
一、构造器创建bean实例(无参构造)
三、调用bean的初始化方法
四、获取到了MyBeanTest的对象
MyBeanTest{name='Mary', age=21}
五、调用bean的销毁方法

**注意:**如果加入例如Bean的后置管理器,则会多处两步,一共七步
(1)通过构造器创建Bean实例(无参构造)
(2)为bean的属性设置值和对其他bean引用(调用set方法)
(3)把bean的实例添加到bean 的后置处理器中
(4)调用bean的初始化方法(需要进行配置初始化的方法)
(5)把bean的实例添加到bean 的后置处理器中
(6)bean可以使用了(对象获取到了)
(7)当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)
完整流程:
(1)首先创建类,实现接口BeanPostProcesser创建后置处理器
(2)实现两个方法,这两个方法对应了上述第3步和第5步的两个过程
(3)在配置文件中加入bean标签用于MyBeanPost后置处理器类的创建

<bean id="myBeanPost" class="com.SSMStudy.Spring5.FactoryBeanStudy.MyBeanPost"></bean>

MyBeanPost类的编写

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之前执行");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之后执行");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

我们将上面的例子重新运行,得到结果:

一、构造器创建bean实例(无参构造)
一、构造器创建bean实例(无参构造)
在初始化之前执行
三、调用bean的初始化方法
在初始化之后执行
四、获取到了MyBeanTest的对象
MyBeanTest{name='Mary', age=21}
五、调用bean的销毁方法

(10)Bean管理的自动装配

根据指定装配规则(根据属性名称或者属性类型),Spring自动将匹配的属性值进行注入
演示:

    <!-- 实现自动装配
        bean标签属性autowire,配置自动装配
        byName根据属性名称进行注入,注入值bean的id值必须和类属性名曾一样
        byType根据属性类型注入
     -->
    <bean id="emp" class="com.SSMStudy.Spring5.FactoryBeanStudy.Emp1" autowire="byName"></bean>
    <bean id="dept" class="com.SSMStudy.Spring5.FactoryBeanStudy.Dept1">
        <property name="dName" value="人事部"></property>
    </bean>
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyBeanAutoWire {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        Emp1 emp = context.getBean("emp", Emp1.class);
        System.out.println(emp);
    }

}

class Emp1{
    private Dept1 dept;

    public void setDept(Dept1 dept) {
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Emp1{" +
                "dept=" + dept +
                '}';
    }
}

class Dept1{
    private String dName;

    public void setdName(String dName) {
        this.dName = dName;
    }

    @Override
    public String toString() {
        return "Dept1{" +
                "dName='" + dName + '\'' +
                '}';
    }
}

(11)操作Bean管理(引入外部属性文件)

演示:配置数据库连接的基础信息
第一种方式 直接配置数据库信息
(1)下载德鲁伊jar包
https://repo1.maven.org/maven2/com/alibaba/druid/
(2)引入德鲁伊jar包
(3)配置德鲁伊连接池

    <!-- 直接配置连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/userDB"></property>
        <property name="username" value="root"></property>
        <property name="password" value="000000"></property>
    </bean>
</beans>

第二种方式 引入外部的属性文件
首先创建jdbc.properties属性文件
在这里插入图片描述(2)把外部的jdbc.properties文件引入到Spring配置文件种

<?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"/>
    <!-- 配置连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${prop.driverClass}"></property>
    <property name="url" value="${prop.url}"></property>
    <property name="username" value="${prop.userName}"></property>
    <property name="password" value="${prop.password]"></property>
</beans>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仲子_real

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值