Bean作用域、生命周期、自动装配

1、IOC操作Bean管理

1.1、Spring有两种类型bean,一种普通bean,另外一种bean(FacoryBean)

(1)普通bean:在配置文件汇总定义bean类型,就是返回类型。
(2)工厂bean:在配置文件定义bean类型可以和返回类型不一样

1.2、工厂bean步骤和代码

第一步:创建实体类,让这个类作为工厂bean,实现接口FactoryBean。
第二步:实现接口里面的方法,在实现的方法中定义返回的bean类型。

(1)创建类MyBean类

package com.lu;

import org.springframework.beans.factory.FactoryBean;

public class MyBean implements FactoryBean<Course>{
    
    
    
    //定义返回bean
    public Course getObject() throws Exception {
    
    
        Course course = new Course();
        course.setCname("自定义返回bean");
        return course;
    }

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

    public boolean isSingleton() {
    
    
        return false;
    }
}

(2)创建类Course类

package com.lu;

//课程类
public class Course {
    
    
    private String cname;

    public void setCname(String cname) {
    
    
        this.cname = cname;
    }

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

(3)配置文件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.lu.MyBean"></bean>

</beans>

(4)测试类HelloTest:

import com.lu.Course;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloTest {
    
    
    public static void main(String[] args) {
    
    
        //加载Spring配置文件
        ApplicationContext context =
                new ClassPathXmlApplicationContext("beans6.xml");
        
        Course course = context.getBean("myBean", Course.class);
        System.out.println(course);
    }
}

(5)结果图:
在这里插入图片描述

2、Bean作用域

2.1、在spring里面,设置创建bean实例是单实例还是多实例?

默认情况下,bean是单实例对象

2.2、如何设置单实例还是多实例

在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例

scope属性值:

第一个值:默认值,singleton,表示单实例

第二个值:prototype,表示多实例

在这里插入图片描述

2.3、singleton和prototype的区别

(1)singleton是单实例,prototype是多实例

(2)当是单实例的时候,在加载spring配置文件的时候就会创建单实例对象

​ 当是多实例的时候,在调用getBean方法的时候创建多实例对象

3、Bean生命周期

3.1、什么是生命周期

从对象创建到对象销毁的过程,就是生命周期。

3.2、bean生命周期

(1)通过构造器创建bean实例(无参构造)

(2)为bean的属性设置值和对其他bean引用(调用set方法)

(3)调用bean的初始化方法(需要进行配置初始化的方法)

(4)bean可以使用了(对象获取到了)

(5)当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)

3.3、代码演示bean生命周期

(1)创建Orders类

package com.lu.bean;

public class Orders {
    
    
    private String oname;

    public Orders() {
    
    
        System.out.println("第一步:执行无参构造,创建bean实例");
    }

    public void setOname(String oname) {
    
    
        this.oname = oname;
        System.out.println("第二步:调用set方法设置属性");
    }

    //创建执行的初始化方法
    //但这是普通方法,需要在bean中用init-method让它执行
    public void initMethod(){
    
    
        System.out.println("第三步:执行初始化方法");
    }

    //创建销毁方法
    //但这是普通方法,需要在bean中用destroy-method让它执行
    public void destroyMethod(){
    
    
        System.out.println("第五步:执行销毁方法");
    }
}

(2)核心配置文件:beans6.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="orders" class="com.lu.bean.Orders" init-method="initMethod" destroy-method="destroyMethod">
        <property name="oname" value="手机"/>
    </bean>

</beans>

(3)创建Test测试类

import com.lu.bean.Orders;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        //加载Spring配置文件
        ApplicationContext context =
                new ClassPathXmlApplicationContext("beans6.xml");

        Orders orders = context.getBean("orders",Orders.class);
        System.out.println("第四步:获取创建bean实例对象");
        System.out.println(orders);

        //手动让bean实例关闭
        ((ClassPathXmlApplicationContext) context).close();
    }
}

(4)运行结果
在这里插入图片描述

3.4、bean的后置处理器
加上后置处理器后,生命周期有七步。加载初始化的前和后执行:(3)和(5)

(1)通过构造器创建bean实例(无参构造)

(2)为bean的属性设置值和对其他bean引用(调用set方法)

(3)把bean实例传递bean后置处理器的方法:postProcessBeforeInitialization

(4)调用bean的初始化方法(需要进行配置初始化的方法)

(5)把bean实例传递bean后置处理器的方法:postProcessAfterInitialization

(6)bean可以使用了(对象获取到了)

(7)当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)

3.5、添加后置处理器的代码和运行结果
(1)创建类,实现接口BeanPostProcessor

package com.lu.bean;

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 bean;
    }

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

(2)在xml配置文件中添加

    <!--配置后置处理器。
    配置后,会对当前配置文件中所有实例都添加上后置处理器-->
    <bean id="myBeanPost" class="com.lu.bean.MyBeanPost"> </bean>

(3)运行结果图
在这里插入图片描述

4、xml自动装配

4.1、什么是自动装配

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

4.2、手动装配

在xml中,手动装配,需要自己写property属性,如下

    <bean id="emp" class="com.lu.autowire.Emp">
        <property name="dept" ref="dept"/>
    </bean>

    <bean id="dept" class="com.lu.autowire.Dept"> </bean>

4.3、自动装配
代码修改如下

    <!--实现自动装配
        bean标签属性:autowire,配置自动装配
        autowire两个值:byName根据属性名称注入
        		       byType根据属性类型注入,当有类型一样,就算id不一样,也报错
        -->
    <bean id="emp" class="com.lu.autowire.Emp" autowire="byName"> </bean>

    <bean id="dept" class="com.lu.autowire.Dept"> </bean>

自动装配 使用的是autowire 属性,autowire有好几个取值:

(1)no 不使用自动装配。Bean依赖关系必须通过property元素定义。
(2)byType 根据属性类型自动装配。BeanFactory查找容器中的全部Bean,如果正好有一个与依赖属性类型相同的Bean,就自动装配这个属性;
如果有多个这样的Bean,Spring不知道注入哪个Bean,就抛出一个异常;如果没有匹配的Bean,就什么都不会发生,属性不会被设置,输出的是null。
(3)byName根据属性名自动装配。BeanFactory查找容器中的全部Bean,找出id与属性的setter方法入参匹配的Bean。找到即自动注入,否则什么都不做,输出的是null。

练习代码:
链接:https://pan.baidu.com/s/1G4zD7WZHjg67O4W4zc91JA
提取码:th2n

猜你喜欢

转载自blog.csdn.net/qq_42524288/article/details/108883266