Spring初学入门(2)——什么Bean、bean的生命周期和bean的装配(bai)

一、了解Bean

1.什么是Bean

通俗一点来说baen就是java对象,只不过是由容器创建,并且由容器管理对象生命周期。
Bean的本质就是Java中的对象,而Spring中的Bean其实就是对实体类的引用,来生产Java类对象,从而实现生产和管理Bean 。

2.Bean的属性

Bean的配置使用xml配置,XML配置文件的根元素是,中包含了多个子元素,每一个子元素定义了一个Bean,并描述了该Bean如何被装配到Spring容器中。关于元素的常用属性如下表所示:
id :bean 再容器的唯一标识
name: bean 在容器中一个标识name ,namek可以有多个使用,或者; 分割
class:bean 创建时要按照那个类类进行创建在这里插入图片描述
注:id必须是Bean中唯一的,而name可以有多个

3.bean的实例化

在Spring中,要想使用容器中的Bean,也需要实例化Bean。实例化Bean有三种方式:
1.构造器实例化
2. 静态工厂方式实例化
3. 实例工厂方式实例化
(其中最常用的是构造器实例化)

1).默认无参构造方法

容器调用无参构造方法创建对象

2).静态工厂实例化

可以自定创建的对象,并且将对象交给容器管理实现

创建静态工厂

/**
 * 静态工厂
 */
public class StaticStudentFactory {


    /**
     * 自定义 Student 对象的创建
     *
     * // 获取了创建对象的权力
     * @return
     */
    public static Student createStudent(){

        Student student = new Student();

        // 比如name 去网络查询 数据库查询
        student.setName("xiaoming");
        student.setId(1000);

        return student;
    }
}

声明使用工厂创建的对象,配置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 像容器声明创建对象  此时创建对象是由静态工厂创建  而不是容器直接创建
        class="com.yyf.factory.StaticStudentFactory" 创建对象的静态工厂
        factory-method="createStudent"  制定创建对象的静态工厂方法


    -->
    <bean id="student" class="com.yyf.factory.StaticStudentFactory" factory-method="createStudent">

    </bean>
</beans>

测试、获取对象

public class StaticFactoryTest {
    public static void main(String[] args) {


        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:factory/staticfactory_bean.xml");


       Student student = (Student) applicationContext.getBean("student");

        System.out.println("student:"+student);
    }
}
3).实例工厂实例化

作用和静态工厂实例化一致
总结:静态工厂实例化和是工厂实例化
作用是根据自己定义需求创建对象,主要用于dao层连接的初始(解决MySQL密码加密问题、密码的加密解密问题)

二、Bean的作用域

1.singleton 单例

在配置文件声明bean 在容器只有一个唯一bean ,当每次获取都是同一个bean
singleton
1.在容器启动只创建一个 id 为student 的bean
2.并且放置在容器中,容器管理他的生命周期

2.propertype 原型

当用户向容器获取bean 时,容器才创建,容器只负责创建,不负责保存维护他的生命周期
1.用户向容器获取时 创建id student2对象
2.每次都创建新的对象
3.容器只负责帮我们创建 不会放置在容器中,不会管理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">


    <!--
       声明让容器创建一个 Student类型的bean  id student1

      scope="singleton"  容器创建bean scope 默认的 作用域是单例singleton
      singleton 1.在容器启动只创建一个 id 为student1 bean  2.并且放置在容器中,容器管理他的生命周期
    -->
    <bean id="student1" class="com.yyf.entity.Student" scope="singleton">
        <property name="id" value="1000"></property>
        <property name="name" value="xiaoming"></property>
    </bean>

    <!--
        声明让容器创建bean 作用域prototype

        prototype 1.用户向容器获取时 创建id student2对象 2.每次都创建新的对象  3.容器只负责帮我们创建 不会放置在容器中,不会管理bean 的生命周期 ,由用户自己负责
    -->
    <bean  id="student2" class="com.yyf.entity.Student" scope="prototype">

    </bean>
</beans>

测试

public class SingletonTest {

    public static void main(String[] args) {


        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("scope/singleton_bean.xml");


        Student student1_A = (Student) applicationContext.getBean("student1");
        System.out.println("student1_A:"+student1_A);

        Student student1_B = (Student) applicationContext.getBean("student1");
        System.out.println("student1_B:"+student1_B);

        System.out.println("student1_A == student1_B:"+(student1_A == student1_B));

        System.out.println("***************************************************");

        // 获取 原型的student2 当获取时 容器创建
        Student student2_A  = (Student) applicationContext.getBean("student2");
        System.out.println("student2_A:"+student2_A);


        // 第二次获取 原型的student2 当获取时 容器创建
        Student student2_B  = (Student) applicationContext.getBean("student2");
        System.out.println("student2_B:"+student2_B);

        System.out.println("student2_A== student2_B:"+(student2_A==student2_B));

    }
}
3.bean的生命周期

bean 的生命周期
单例的bean:随着容器的启动,bean 创建,容器并负责维护bean的生命周期
原型的bean: 容器启动时不创建bean,当用户获取时容器才创建bean,每次都是新的bean,容器部管理他的生命周期

三、bean的装配

什么是bean的装配

Bean的装配可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Spring容器支持多种形式的Bean的装配方式,如基于XML的装配、基于注解(Annotation)的装配和自动装配(其中最常用的是基于注解的装配)

1)基于xml装配
设置值装配

1.必有由无参构造 2.必须有setter方法

构造方法装配

使用setter方法注入,必备条件:**Bean类必须有一个无参构造方法,Bean类必须为属性提供setter方法
1.必须有构造方法 2.使用<constructor-arg 进行初始化

示例
先附上student实体类

public class Student {
    private int id;
    private String name;

    private  List<String> courseList ;

    public List<String> getCourseList() {
        return courseList;
    }

    public void setCourseList(List<String> courseList) {
        this.courseList = courseList;
    }

    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public Student(int id, String name, List<String> courseList) {
        this.id = id;
        this.name = name;
        this.courseList = courseList;
    }
    public Student() {
        System.out.println("student无参构造被调用");
    }
    /**
     * 初始化方法
     */
    public void  init(){
        System.out.println("name:"+name+"Student-init()");
    }


    /**
     * 销毁方法
     */
    public void destroy(){
        System.out.println("name:"+name+"Student-destroy()");
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", courseList=" + courseList +
                '}';
    }
}

dao层有一个studentDao接口 有一个方法为findStudentById用于测试

public interface IStudentDao {
    /**
     * 更具id 查找student
     * @param id
     * @return
     */
    Student findStudentById(int id);
}

dao.impl层有一个studentDaoImpl实现Dao层接口

@Repository// 标记当前类是dao层
public class IStudentDaoImpl implements IStudentDao {
    public Student findStudentById(int id) {
        Student student = new Student();
        student.setId(id);
        student.setName("鞠婧祎");
        return student;
    }
}

service层 StudentService

public interface StudentService {
        /**
         * 更具id 查找student
         * @param id
         * @return
         */
        Student findStudentById(int id);
}

service.impl实现层StudentServiceImpl

//@Component  // 将当前类 生成对象并加入到 容器
@Service  // 继承 @Component 功能
public class StudentServiceImpl implements StudentService {

    // 使用注入的注解 注入bean
    //@Autowired  // 去容器中 根据对应类型 查找对应bean ,并设置到当前 属性中  //如果容器有 多个类型的bean则报错
//        @Qualifier("studentDao1")  //  @Qualifier 与@Autowired 配合 ,当根据类型找到多个时 使用  @Qualifier 按照id  或者name 查找为一个bean

    //        @Resource // 首先按照 id 为属性名studentDao 去容器中找到对应的bean 2.如果找不到 在按照类型去查找 如果找到多个 报错
    //@Resource(name = "studentDao1")  // 如果传递 name  则按照 name 为studentDao1 去容器中查找 id 或者name 相同的bean
    @Autowired
    private IStudentDao studentDao ;

    public IStudentDao getStudentDao() {
        return studentDao;
    }

    public void setStudentDao(IStudentDao studentDao) {
        this.studentDao = studentDao;
    }

    public StudentServiceImpl() {
    }

    public StudentServiceImpl(IStudentDao studentDao) {
        this.studentDao = studentDao;
    }

    public Student findStudentById(int id) {
        return studentDao.findStudentById(id);
    }
}


xml配置,1.必须有构造方法 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">

    <!--
         基于xml setter 装配 设置值 必须由两个条件 :1.有无参构造 2.要有setter 方法 必不可少
    -->
    <bean id="student1"  class="com.qfedu.entity.Student">
        <property name="name" value="xiaoming"></property>
        <property name="id" value="1000"></property>
        <property name="courseList" >
           <list>
                <value>java</value>
                <value>c++</value>
                <value>python</value>
            </list>
       </property>
    </bean>

    <!--
        基于xml 构造方法的装配 初始化
        <constructor-arg 给构造参数 传数据
                index="0" 下标0 代表第一个参数
                value="1001" 第一个参数的值
    -->
    <bean id="student2" class="com.qfedu.entity.Student">
        <constructor-arg index="0" value="1001"></constructor-arg>
        <constructor-arg index="1" value="xiaohua"></constructor-arg>
        <constructor-arg index="2">
            <list>
                <value>java</value>
                <value>c++</value>
                <value>python</value>
            </list>
        </constructor-arg>
    </bean>
    <bean id="studentDao" class="com.yyf.dao.impl.IStudentDaoImpl"></bean>
    <bean id="studentService" class="com.yyf.service.StudentServiceImpl">
        <!--
         ref="studentDao"  通过ref  引用id studentDao的bean 进行装配
         -->
        <property name="studentDao" ref="studentDao">
        </property>
    </bean>
</beans>

测试

public class XmlTest {

    public static void main(String[] args) {


        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("xml/settter_bean.xml");



        // 按照类型 去获取 Bean  如果容器中只有一个 bean 可以,如果有多个同类型的bean
        // 则报错 available: expected single matching bean but found 2: student1,student2
        // 容器找到了 两个bean ,但是不确定你需要那一个bean
        // 需要你传更确且  name  id  来查找
        Student student1 = (Student) applicationContext.getBean("student1");
        System.out.println("student1:"+student1);


        Student student2 = (Student) applicationContext.getBean("student2");
        System.out.println("student2:"+student2);


        // 获取类型  StudentService.class 实例 bean
        StudentService studentService = applicationContext.getBean(StudentService.class);

        Student student3 =   studentService.findStudentById(2000);
        System.out.println("student3:"+student3);

    }
}
4.基于注解的装配

基于XML的装配可能会导致XML配置文件过于臃肿,给后续的维护和升级带来一定的困难。为此,Spring提供了对Annotation(注解)技术的全面支持。

1)注入的注解 设置值

@Autowired:去容器中 根据对应类型 查找对应bean ,并设置到当前 属性中 如果容器有 多个类型的bean则报错

@Qualifier(“studentDao1”) : @Qualifier 与@Autowired 配合 ,当根据类型找到多个时 使用 @Qualifier 按照id 或者name 查找为一个bean

@Resource:首先按照 id 为属性名studentDao 去容器中找到对应的bean 2.如果找不到 在按照类型去查找 如果找到多个 报错

@Resource(name = “studentDao1”) 如果传递 name 则按照 name 为studentDao1 去容器中查找 id 或者name 相同的bean

2) 生成bean的注解

这四个注解都是都一个作用生成bean,@Component是其他三个的父类

@Component

@Repository 指明当前实例 是dao 层的实例

@Service 指明当前实例是service 层的实例

@Controller 指明当前实例是控制 层的实例 但是springmvc 中控制层只能用 @Controller

3)半自动注解装配

只能进行注入,使注入的注解生效,bean的生成还需要在xml进行配置*实现是 <context:annotation-config></context:annotation-config>

1.首先在容器中声明bean

2.使用对应注入的注解 注入bean

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"
       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 https://www.springframework.org/schema/context/spring-context.xsd">
    <!--
        作用就是让 注入的注解生效
    -->
    <context:annotation-config></context:annotation-config>
    <!--1. 声明 bean-->
    <bean id="studentDao" class="com.yyf.dao.impl.IStudentDaoImpl"></bean>
    <bean id="studentService" class="com.yyf.service.StudentServiceImpl">
    </bean>
</beans>

测试

   public class StudentServiceImpl implements StudentService {
    
        // 使用注入的注解 注入bean
        @Autowired  // 去容器中 根据对应类型 查找对应bean ,并设置到当前 属性中
        private IStudentDao studentDao ;
    
        public IStudentDao getStudentDao() {
            return studentDao;
        }
    
        public void setStudentDao(IStudentDao studentDao) {
            this.studentDao = studentDao;
        }
    
        public Student findStudentById(int id) {
            return studentDao.findStudentById(id);
        }
    }
4).自动注解 context:component-scan

自动注解就是 通过注解自动的生成bean 并经行装配

实现:在xml 声明 context:component-scan 使对应包下的 注入的注解(@Autowired @Qualifie @Resource )生成bean的注解(@Component@Repository @Service @Controller)生效

实现
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"
       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 https://www.springframework.org/schema/context/spring-context.xsd">



    <!--
        开启 自动注解功能 使 注入的注解(@Autowired @Qualifie @Resource )生成bean的注解(@Component@Repository @Service @Controller)生效
    -->
     <context:component-scan base-package="com.yyf"></context:component-scan>


</beans>

2.标记需要 生成 bean 和主要注入的属性
dao层


//@Component("studentDao1")  // 将IStudentDaoImpl 生成实例 并加入到容器中 为生成的bean 制定id studentDao1
@Repository  // 标记当前类是dao层
public class IStudentDaoImpl implements IStudentDao {
    public Student findStudentById(int id) {

        Student student = new Student();
        student.setId(id);
        student.setName("xxxx");
        return student;
    }
}

service层


//@Component  // 将当前类 生成对象并加入到 容器
@Service  // 继承 @Component 功能
public class StudentServiceImpl implements StudentService {

        // 使用注入的注解 注入bean
//        @Autowired  // 去容器中 根据对应类型 查找对应bean ,并设置到当前 属性中  //如果容器有 多个类型的bean则报错
//        @Qualifier("studentDao1")  //  @Qualifier 与@Autowired 配合 ,当根据类型找到多个时 使用  @Qualifier 按照id  或者name 查找为一个bean

//        @Resource // 首先按照 id 为属性名studentDao 去容器中找到对应的bean 2.如果找不到 在按照类型去查找 如果找到多个 报错
        @Resource(name = "studentDao1")  // 如果传递 name  则按照 name 为studentDao1 去容器中查找 id 或者name 相同的bean
        private IStudentDao studentDao ;

        public IStudentDao getStudentDao() {
            return studentDao;
        }

        public void setStudentDao(IStudentDao studentDao) {
            this.studentDao = studentDao;
        }

        public Student findStudentById(int id) {
            return studentDao.findStudentById(id);
        }
    }

测试


    public static void main(String[] args) {


        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("annotation/auto_bean.xml");




        // 获取类型  StudentService.class 实例 bean
        StudentService studentService = applicationContext.getBean(StudentService.class);

        Student student3 =   studentService.findStudentById(2000);
        System.out.println("student3:"+student3);
    }
5)基于xml 自动装配

所谓自动装配,就是将一个Bean自动的注入到到其他Bean的Property中。 Spring的元素中包含一个autowire属性,我们可以通过设置autowire的属性值来自动装配Bean。autowire属性有5个值.

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="studentDao" class="com.qfedu.dao.impl.IStudentDaoImpl"></bean>


    <bean id="studentDao2" class="com.qfedu.dao.impl.IStudentDaoImpl"></bean>

    <!--
        基于 xml 自动装配
          autowire="byType" StudentServiceImpl 中属性 需要那些bean 就去根据类型去容器查找对应bean
          autowire="byName"  StudentServiceImpl 根据属性中对应属性名 作为id 去查找 ,如果找不到就不设置对应的属性
          autowire="constructor" 1.首先根据类型去类型 去查找,如果找到一个就设置对应bean 
                                   2.如果找到两个 则根据参数变量名去查找   根据构造器中对应 参数名作为id 去查找 查找不到就传null 
      -->
    <bean id="studentService" class="com.qfedu.service.StudentServiceImpl"  autowire="constructor">
    </bean>

</beans>

测试

/**
 * xml 自动装配
 */
public class XMLAuto {

    public static void main(String[] args) {

        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("xml/xml_auto_bean.xml");



        // 获取类型  StudentService.class 实例 bean
        StudentService studentService = applicationContext.getBean(StudentService.class);

        Student student3 =   studentService.findStudentById(2000);
        System.out.println("student3:"+student3);

    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值