Spring-bean

Spring-bean

Bean配置

​ Spring可以看做是一个大型的工厂,用于生产和管理Spring容器中的Bean。要使用这个工厂生产和管理Bean,则需要将Bean配置在Spring的配置文件中。Spring支持XML与properties两种格式的配置文件,这里我采用XML的形式。

​ 先来了解一个bean的常用属性

属性作用
idBean在BeanFactory中的唯一标识,要想获取Bean实例,则需要Id
classBean的具体实现类,使用类名
scopeBean的作用域,当为singleton时,SpringIOC容器仅生成和管理一个Bean实例,当为prototype时,每次请求则会创建一个。
标签的子元素,使用构造器方法注入时,指定构造器的参数。index属性指定参数的序号,ref属性指定与其他Bean的引用关系,type属性指定参数类型,value指定参数的常量值
元素的子元素,用于设置一个值。name属性为Bean实例的属性名称,value属性为Bean的属性值,ref属性指定属性与其他Bean的引用关系
元素的子元素,用于封装Map类型的依赖注入
元素的子元素,用于封装Set类型的依赖注入
类型的子元素,用于设置键值对
元素的子元素,用于封装List类型的依赖注入

Bean的实例化

​ 为什么需要实例化?如果我们想使用一个对象,则这个对象就需要实例化。在Spring中,想使用一个Bean,则需要实例化。实例化的方式有三种,即构造方法实例化,静态工厂实例化和实例工厂实例化。

构造方法实例化

BeanClass.java

package instance;

public class BeanClass {
    public String name;
    public BeanClass(){
        name="构造方法实例化";
    }
    public BeanClass(String names){
        name=names;
    }
}
package test;
//测试类
import instance.BeanClass;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BeanClass o = (BeanClass)context.getBean("beanClass");
        System.out.println(o+o.name);
    }
}
<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="beanClass" class="instance.BeanClass"/>
</beans>

目录
在这里插入图片描述
运行结果为
在这里插入图片描述

静态工厂实例化

​ 新建一个类,在类中使用静态方法创建想实例化的Bean,从而达到静态工厂实例化。在配置Bean时,class属性指定的时新建的静态工厂类,因为是让静态工厂去实例化这个Bean,而还需用factory-method属性去指定使用了静态工厂类中哪个方法去实例化了想实例化的Bean。
新建一个静态工厂类

package instance;

public class BeanStaticClass {
    private static BeanClass beanInstance=new BeanClass("静态方法实例化");
    public static BeanClass beanInstance(){  ///实例化实例的方法
        return beanInstance;
    }
}

在配置文件中加入

<bean id="instanceClass" class="instance.BeanStaticClass" factory-method="beanInstance"/>

测试一下

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BeanClass o = (BeanClass)context.getBean("instanceClass");
        System.out.println(o+o.name);
    }
}

结果
在这里插入图片描述

实例工厂实例化

​ 新建一个类,在类中使用方法创建想实例化的Bean,从而达到实例工厂实例化。在配置Bean时,,用factory-bean去指定实例化工厂,因为是让实例工厂去实例化这个Bean,而还需用factory-method属性去指定使用了实例工厂类中哪个方法去实例化了想实例化的Bean。

​ 实例工厂类

package instance;
public class BeanInstanceClass {
    public BeanClass beanInstanceClass(){
        return new BeanClass("调用实例工厂方法实例化Bean");
    }
}

配置文件

<bean id="instanceFactory" class="instance.BeanInstanceClass"/>   <!--    实例工厂-->
<bean id="instanceClass" class="instance.BeanInstanceClass" factory-bean="instanceFactory" factory-method="beanInstanceClass"/>

测试类

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BeanClass o = (BeanClass)context.getBean("instanceClass");
        System.out.println(o+o.name);
    }
}

结果
在这里插入图片描述

bean的生命周期

​ 我对bean生命周期的理解是这样的,由于scope的值可以为singleton时,即只会创建一个Bean实例,则Spring可以对其生命周期进行追踪,但是当scope的值为prototype时,由于每次请求都会创建一个新的bean,所以Spring只负责创建,创建以后则不会对Bean的=进行管理。

​ 当创建Bean之前,可以先对其初始化,在Bean销毁的时候,也可以对其自定义销毁。举个例子

BeanLife.java

package instance;

public class BeanLife {
    public void initBefore(){
        System.out.println("执行自定义的初始化方法");
    }
    public void destroyAfter(){
        System.out.println("自定义销毁");
    }
}

xml文件

<bean id="beanLife" class="instance.BeanLife" init-method="initBefore" destroy-method="destroyAfter"/>
  • init-method指定了在得到这个Bean之前需要执行的方法
  • destroy-method指定了在销毁这个Bean之前需要执行的方法

测试函数

public class Test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("获得Bean前");
        BeanLife o = (BeanLife)context.getBean("beanLife");
        System.out.println("获得Bean后");
        context.close();
    }
}

Bean的装配方式

之前一直不理解,Bean的实例化与Bean的装配有什么区别,通过大量的查阅资料,算是理解了。实例化只是给Bean开辟了空间,而装配则是给Bean的属性赋值。在Spring中,支持xml与注解两种方式对Bean的装配。而对Bean装配的过程,也就是对Bean依赖注入的过程。

基于XML方式的装配

​ 基于XML的注入方式,在前面的文章我也大概提到过,有两种方式,一种是构造器注入,一种是Setter方法注入。

  • 使用构造器注入,则需要带参数的构造方法,这是非常重要的。

  • 使用setter方法注入,则需要无参构造方法,以及set方法。

举个例子

User.java

package pojo;

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

public class User {
    private String name;
    private List<String> hobby;
    private Map<String,String> family;
    private Set<String> like;
    private String[] array;

    public User() {
    }

    public User(String name, List<String> hobby, Map<String, String> family, Set<String> like, String[] array) {
        this.name = name;
        this.hobby = hobby;
        this.family = family;
        this.like = like;
        this.array = array;
    }

    public String getName() {
        return name;
    }

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

    public List<String> getHobby() {
        return hobby;
    }

    public void setHobby(List<String> hobby) {
        this.hobby = hobby;
    }

    public Map<String, String> getFamily() {
        return family;
    }

    public void setFamily(Map<String, String> family) {
        this.family = family;
    }

    public Set<String> getLike() {
        return like;
    }

    public void setLike(Set<String> like) {
        this.like = like;
    }

    public String[] getArray() {
        return array;
    }

    public void setArray(String[] array) {
        this.array = array;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", hobby=" + hobby +
                ", family=" + family +
                ", like=" + like +
                ", array=" + Arrays.toString(array) +
                '}';
    }
}
    <!--使用构造器依赖注入-->
    <bean id="userCon" class="pojo.User">
        <constructor-arg name="name" value="cx"/>
        <constructor-arg name="family">
            <map>
                <entry key="father" value="cc"/>
                <entry key="mother" value="xx"/>
            </map>
        </constructor-arg>
        <constructor-arg name="array">
            <array>
                <value>arry1</value>
                <value>arry2</value>
            </array>
        </constructor-arg>
        <constructor-arg name="hobby">
            <list>
                <value>list1</value>
                <value>list2</value>
            </list>
        </constructor-arg>
        <constructor-arg name="like">
            <set>
                <value>set1</value>
                <value>set2</value>
            </set>
        </constructor-arg>
    </bean>
<!--使用setter方法注入-->
    <bean id="beanSetter" class="pojo.User">
        <property name="name" value="lc"/>
        <property name="hobby">
            <list>
                <value>list1_setter</value>
                <value>list2_setter</value>
            </list>
        </property>
        <property name="family">
            <map>
                <entry key="father" value="cc_setter"/>
                <entry key="mom" value="xx_setter"/>
            </map>
        </property>
        <property name="like">
            <set>
                <value>set1_setter</value>
                <value>set2_setter</value>
            </set>
        </property>
        <property name="array">
            <array>
                <value>arry1_setter</value>
                <value>arry2_setter</value>
            </array>
        </property>
    </bean>

测试函数

public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    Object con = (User)context.getBean("userCon");
    User o = (User)context.getBean("beanSetter");
    System.out.println(con.toString());
    System.out.println(o.toString());
}

基于注解的装配

常见的注解
注解功能
@Component表示为Spring的一个组件对象(bean),可以作用在任何层次上
@Controller标注一个控制器类,功能与@Component相同
@Service标注一个业务逻辑组件类,功能与@Component相同
@Repository标注数据访问层,功能与@Component相同
@Autowired可以对类成员变量,方法以及构造方法进行标注,完成自动装配。默认按照类型进行装配
@Resource与@Autowried功能相同,唯一的区别是默认按照名称进行装配
@Qualifier与注解@Autowired配合使用,当注解@Autowired需要按照名称进行装配时,可以@Qualifier来指定名称

在Spring中,还需要引入context命名空间,来扫描标注的组件对象。

<context:component-scan base-package="annotation"/>
<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
       https://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd"
>

完整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
       https://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd"
>
    <context:component-scan base-package="annotation"/>
    <bean id="beanClass" class="instance.BeanClass"/>
    <bean id="staticClass" class="instance.BeanStaticClass" factory-method="beanInstance"/>
    <bean id="instanceFactory" class="instance.BeanInstanceClass"/>   <!--    实例工厂-->
    <bean id="instanceClass" class="instance.BeanInstanceClass" factory-bean="instanceFactory" factory-method="beanInstanceClass"/>
    <bean id="beanLife" class="instance.BeanLife" init-method="initBefore" destroy-method="destroyAfter"/>
    <!--使用构造器依赖注入-->
    <bean id="userCon" class="pojo.User">
        <constructor-arg name="name" value="cx"/>
        <constructor-arg name="family">
            <map>
                <entry key="father" value="cc"/>
                <entry key="mother" value="xx"/>
            </map>
        </constructor-arg>
        <constructor-arg name="array">
            <array>
                <value>arry1</value>
                <value>arry2</value>
            </array>
        </constructor-arg>
        <constructor-arg name="hobby">
            <list>
                <value>list1</value>
                <value>list2</value>
            </list>
        </constructor-arg>
        <constructor-arg name="like">
            <set>
                <value>set1</value>
                <value>set2</value>
            </set>
        </constructor-arg>
    </bean>
<!--使用setter方法注入-->
    <bean id="beanSetter" class="pojo.User">
        <property name="name" value="lc"/>
        <property name="hobby">
            <list>
                <value>list1_setter</value>
                <value>list2_setter</value>
            </list>
        </property>
        <property name="family">
            <map>
                <entry key="father" value="cc_setter"/>
                <entry key="mom" value="xx_setter"/>
            </map>
        </property>
        <property name="like">
            <set>
                <value>set1_setter</value>
                <value>set2_setter</value>
            </set>
        </property>
        <property name="array">
            <array>
                <value>arry1_setter</value>
                <value>arry2_setter</value>
            </array>
        </property>
    </bean>
</beans>
  • 忽略配置的bean,此处没用到
    在这里插入图片描述
    TestDao.java
package annotation.dao;

public interface TestDao {
    public void print();
}
package annotation.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class TestDaoImp implements TestDao {
    public void print() {
        System.out.println("TestDaoImp");
    }
}

TestService.java

package annotation.service;

public interface TestService {
    public void print();
}

TestServiceImp.java

package annotation.service;
import annotation.dao.TestDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import test.Test;
@Service
public class TestServiceImp implements TestService {
    @Autowired
    @Qualifier(value = "testDaoImp")
    private TestDao testDao;
    public void print() {
        testDao.print();
        System.out.println("TestServiceImp");
    }
}

TestController.java

package annotation.controller;

import annotation.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;

@Controller
public class TestController {
    @Resource
    private TestService testService;
    public void print(){
        testService.print();
    }
}

测试类

package test;
import annotation.controller.TestController;
import annotation.service.TestService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pojo.User;
public class Test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        TestController con = (TestController)context.getBean("testController");
        con.print();
        TestService testService = (TestService)context.getBean("testServiceImp");
        testService.print();
    }
}

otation.service.TestService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import pojo.User;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext.xml”);
TestController con = (TestController)context.getBean(“testController”);
con.print();
TestService testService = (TestService)context.getBean(“testServiceImp”);
testService.print();
}
}
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值