Spring中Bean

Bean的配置

  • spring可以看成一个大型的工厂,这个工厂主要是来生产和管理Spring容器中的Bean,只需要对Spring的配置文件进行配置就可以使用这个工厂。
  • Spring容器支持Xml和Properties两种格式的配置文件,常用的是xml,通过配置xml来注册并管理Bean之间的依赖关系。
  • 根元素
  • 子元素,每一个bean代表一个Bean,并描述了Bean如何装配到Spring容器中。
  • @@@@
  • id: 每个bean的唯一的表示,Spring容器对Bean的配置,管理通过该属性来完成。
  • name: spring容器同样可以通过该容器进行对Bean的配置和管理,name可以对Bean指定多个名称,用逗号隔开。
  • class: 指定Bean的具体的实现类
  • scope:设定Bean实例的作用域:singleton(单例),prototype(原型)等默认是singleton
  • constructor-arg : 元素的子元素,可以使用此元素传入的构造参数进行实例化,该元素的index属性指定构造参数的序号(从0开始),type属性指定构造参数的类型,通过value属性或者ref属性来直接指定,
  • property: 元素的子元素 ,用于调用Bean实例中的setter方法来完成属性的赋值,从而完成依赖注入,该元素的name指定Bean实例中的相应的属性名,ref属性或value属性用于指定参数值。
  • ref: 上面两个的子元素,也可用于指定指定Bean工厂的某个Bean实例的引用
  • value: 上上面两个的子元素,也可用于指定一个常量值。
  • lsit:用于封装list或者数组类型的依赖注入
  • set:用于封装set类型的依赖注入
  • map:用于封装map类型的依赖注入
  • entry:的子元素,用于设置一个键值对。
<?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-4.3.xsd">
        <!--使用id属性定义bean1,其对应的实现类为com.itheima.Bean1-->
        <bean id="bean1" class="com.itheima.Bean1"></bean>
        <!--使用name属性bean2,其对应的实现类是com.itherima.Bean2-->
        <bean name="bean2"class="com.itheima.Bean2"></bean>
        <!--Bean中没有id或者name,class的值就会作为id来使用-->

</beans>

Bean的实例化

在spring容器中,也要实例化Bean,实例化Bean有三种方式,分别是:构造器实例化,静态工厂实例化,实例工厂方式实例化,

构造器实例化

Bean1

package com.yzb.chapter02.example;
/*
* 使用无参构造方法去实例化Bean
* */
public class Bean1 {

}

Test

package com.yzb.chapter02.example;

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

public class Test {
    public static void main(String[] args) {
        String path = "bean1.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
       Bean1 bean1 = (Bean1) applicationContext.getBean("bean1");
        System.out.println(bean1);
    }
}

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-4.3.xsd">
    <bean id="bean1" class="com.yzb.chapter02.example.Bean1"></bean>

</beans>

静态工厂方式实例化

  • 配置文件中class指定的是工厂实现类的路径,还要制定使用的工厂方法,spring容器不知到使用的是什莫容器。

Bean2

package com.yzb.chapter02.example1;

public class Bean2 {
}

MyBeanFactory

package com.yzb.chapter02.example1;

public class MyBeanFactory {
    //使用自己的工厂创建Bean2的实例
    public static Bean2 createBean(){
        return new Bean2();
    }
}

bean2.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-4.3.xsd">
    <bean id="bean2" class="com.yzb.chapter02.example1.MyBeanFactory" factory-method="createBean"></bean>

</beans>

Test1

package com.yzb.chapter02.example1;

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

public class Test1 {
    public static void main(String[] args) {
        String path = "com/yzb/chapter02/example1/bean2.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
        Bean2 bean2 = (Bean2) applicationContext.getBean("bean2");
        System.out.println(bean2);
    }
}

实例工厂方式实例化

  • 在配置文件中class指定不是实例化的类,而是通过factory-bean指定配置的实例工厂,然后使用factory-method方法确定要是的是哪个方法。

Bean3

package com.yzb.chapter02.example2;

public class Bean3 {

}

MyBean3Factory

package com.yzb.chapter02.example2;

public class MyBean3Factory {
    public MyBean3Factory() {
        System.out.println("bean3工厂实例化中");
    }
    //常见Bean3实例化的方法
    public Bean3 createBean(){
        return new Bean3();
    }
}

bean3.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-4.3.xsd">
    <bean id="myBean3Factory" class="com.yzb.chapter02.example2.MyBean3Factory"/>
   <bean id="bean3" factory-bean="myBean3Factory" factory-method="createBean"/>
</beans>

Test3

package com.yzb.chapter02.example2;

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

public class Test3 {
    public static void main(String[] args) {
        //指定配置文件
        String path = "com/yzb/chapter02/example2/bean3.xml";
        //ApplicationContext加载配置文件,并对Bean进行实例化
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
        System.out.println(applicationContext.getBean("bean3"));
    }
}

Bean的作用域

  • 通过Spring容器创建一个Bean实例的时候,还可以指定它的作用域。
  • singleton:(单例): 使用singleton定义的Bean实例在spring容器中只有一个实例,就是说无论多少个Bean引用它,始终指向同一个对象
  • prototype(原型):每次通过Spring容器获取prototype定义的Bean时,容器都将创建一个新的Bean实例。
  • request:再一次Http请求,容器放回Bean的同一个实例,对于不同的HTTP请求则会产生一个新的Bean,而且该Bean仅在当前的HTTP Request内有效
  • session:在一次HTTP Session中,容器会返回该Bean的同一个实例,对于不同的Http请求则会产生一个新的Bean,仅在当前的HTTP Session中有效。
  • globalSession:在一个全局的HTTP Session中,容器回返回该Bean的同一个实例,仅在使用protlet上下文时有效。
  • application:为每个ServletContext对象创建一个实例,仅在Web相关的ApplicationContext中生效。
  • websocket :为每个WebSocket对象创建一个实例,仅在Web相关的ApplicationContext中生效。

singleton(单例)作用域

  • 只要id与该Bean的id属性相匹配,就会返回同一个Bean的实例。

Bean4

package com.yzb.chapter02.example3;

public class Bean4 {
}

bean4.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-4.3.xsd">
    <bean id="bean4" class="com.yzb.chapter02.example3.Bean4"></bean>

</beans>

Test4

package com.yzb.chapter02.example3;

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

public class Test4 {
    public static void main(String[] args) {
        //定义配置文件
        String path ="com/yzb/chapter02/example3/bean4.xml";
        //加载配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
        //输出获得实例
        System.out.println(applicationContext.getBean("bean4"));
        System.out.println(applicationContext.getBean("bean4"));

    }
}

运行结果

在这里插入图片描述

  • 是同一个对象,所以singleton调用的同一个对象。

prototype(原型)作用域

bean4.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-4.3.xsd">
<bean id="bean4" class="com.yzb.chapter02.example3.Bean4" scope="prototype"></bean>

</beans>

结果

在这里插入图片描述

  • 创建了一个新的Bean的实例,所以它的位置时不一样的。

Bean的生命周期

  • Spring容器可以管理singleton作用域的Bean的生命周期,在这个作用域下,Spring可以清楚的知道Bean何时被创建,何时完成初始化操作,以及销毁操作,
  • 对于prototype作用域的Bean对象的时候,Spring容器只负责创建一个新的Bean,之后的操作交给客户端代码完成,Spring容器不在跟踪它的生命周期,对于每一次请求,spring容器都会创建一个新的Bean,但后续的操作不负责。

生命周期过程图

在这里插入图片描述

  • 根据配置情况调用Bean的无参构造方法或者工厂方法实例化;
  • 利用依赖注入完成Bean中的所有的属性的配置注入;
  • 如果Bean实现了BeanNameAware接口,则Spring调用Bean的setBeanName()的方法传入当前的id的值;
  • 如果Bean实现了BeanFactoryAware接口,则Spring调用Bean的setBeanFactory()的方法传入当前的工厂实例的引用。
  • 如果Bean实现了ApplicationContextAware接口,则Spring调用setApplicaitonContext()方法传入当前的ApplicationContext的实例的引用。
  • 如果BeanPostProcessor和Bean关联postProcessBeforeInitialization()对Bean进行加工操作,
  • 如果Bean实现了initializingBean接口,则Spring将调用afterPropertiesSet()方法,
  • 如果在配置文件中通过init-method属性指定初始化的方法,调用该初始化的方法
  • 如果BeanPostProcessor和B关联,spring调用该接口的初始化方法postProcessAfterInitialization().这是的Bean,已经可以被应用系统使用了。
  • 如果Bean指定了作用域的范围,如果作用域是singleton,将它Spring Ioc缓冲池中,触发Spring对该Bean的生命周期的管理,如果是prototype的作用域,将交给调用者管理生命周期,Spring将不在管理Bean.
  • 如果Bean实现了DisposableBean接口,spring容器调用destory()方法将Spring容器中的singleton作用域的Bean销毁,如果在配置文件中通过destory-method属性指定Bean的销毁方法。

Bean的装配

基于XML的装配

  • 设置注入(Setter Injection) 和 构造注入(Constructor Injection)

设置注入(Setter Injection)

  • 满足条件
  • Bean类提供一个默认的无参的构造方法
  • Bean类必须为需要注入的属性提供对应的setter方法。

构造注入(constructor Injection)

  • 满足条件
  • Bean类需要提供一个所有参数的构造方法,

XML装配代码

User

package com.yzb.chapter02.example4;

import java.util.List;

public class User {
    private String username;
    private Integer password;
    private List<String> list;
    /*
    * 使用构造注入
    * 提供所有参数的有参构造方法
    * */

    public User(String username, Integer password, List<String> list) {
        this.username = username;
        this.password = password;
        this.list = list;
    }
    /*
    * 使用设值注入
    * 提供默认的空参构造方法
    * 为所有的属性提供setter方法
    * */

    public User() {
        super();
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(Integer password) {
        this.password = password;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password=" + password +
                ", list=" + list +
                '}';
    }
}

Bean5.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-4.3.xsd">
    <!--使用构造注入装配Bean的实例-->
    <bean id="user1" class="com.yzb.chapter02.example4.User">
        <constructor-arg index="0" value="tome"/>
        <constructor-arg index="1" value="123456"/>
        <constructor-arg index="2">
            <list>
                <value>constructorvalue1</value>
                <value>constructorvalue2</value>
            </list>
        </constructor-arg>
    </bean>
    <!--使用设置注入装配Bean的实例-->
    <bean id="user2" class="com.yzb.chapter02.example4.User">
        <property name="username" value="tome"></property>
        <property name="password" value="23445"></property>
        <property name="list">
            <list>
                <value>setlistvalue1</value>
                <value>setlistvalue2</value>
            </list>
        </property>
    </bean>

</beans>

Test5

package com.yzb.chapter02.example4;

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

public class Test5 {
    public static void main(String[] args) {
        //定义配置文件的路径
        String path ="com/yzb/chapter02/example4/bean5.xml";
        //加载配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
        //构造方式输出结果
        System.out.println(applicationContext.getBean("user1"));
        //设置方式输出结果
        System.out.println(applicationContext.getBean("user2"));
    }
}

结果

在这里插入图片描述

基于Annotation的装配

  • 如果Bean过多的话,那末使用xml配置文件将会太过臃肿,所以可以使用注解的技术的支持。
  • @Component:仅仅表示一个组件(Bean),可以用在任何的层次,使用时只需要将该注解标注在相应的类的上面即可。
  • @Repository:用于将数据访问层(DAO层)的类表示为Spring中的Bean,其功能与@Component相同
  • @Service:通常作用在业务层(Service层),用于将业务层的类表示为Spring中 Bean,其功能与@Component相同.
  • @Controller:通常作用在控制层(Spring Mvc的Controller),用于将控制层的类表示为Spring的Bean,其功能与@Component相同.
  • @Autowired:用于对Bean的属性变量,属性的setter方法以及构造方法进行标注,配合对应的注解处理器完成Bean的自动装配工作,默认按照Bean的类型进行装配。
  • @Resource:作用与@ Autowired相同,区别,@Autowired按照Bean的类型装配,@Resource默认按照实例名称进行自动装配,它的属性由name和type,Spring将name解析为Bean的实例名称,type解析为Bean的实例类型,若指定了对应的name或者type,则将按照对应的方式进行装配,若没有指定,则先按照name进行装配,name没找到,则找type进行装配,若也没又找到,则抛出异常。
  • @Qualifier:与@Autowired注解配合使用,将默认的Bean类型的装配方式,更改为Bean实例名称的方式装配,实例名称由@Qualifier注解的参数指定。
  • 在代码中,主要用到@Repository,@Service,@Controller.

基于Annotation的装配的代码

UserDAO

package com.yzb.chapter02.example5;

public interface UserDao {
    public void say();
}

UserDaoImpl

package com.yzb.chapter02.example5;

import org.springframework.stereotype.Repository;

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void say() {
        System.out.println("userDao ...save.....");
    }
}

UserService

package com.yzb.chapter02.example5;

public interface UserService {
    public void say();
}

UserServiceImpl

package com.yzb.chapter02.example5;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service("userService")
public class UserServiceImpl implements UserService {
    @Resource(name="userDao")
    private UserDao userDao;
    @Override
    public void say() {
        userDao.say();
        System.out.println("userService ...save....");
    }
}

UserController

package com.yzb.chapter02.example5;

public interface UserController {
    public void  say();
}

UserControllerImpl

package com.yzb.chapter02.example5;

import org.springframework.stereotype.Controller;

import javax.annotation.Resource;

@Controller("userController")
public class UserControllerImpl implements UserController {
    @Resource(name = "userService")
    private UserService userService;

    @Override
    public void say() {
        userService.say();
        System.out.println("userController .... save.....");
    }
}

bean6.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-4.3.xsd
      http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    <!--使用context的命名控件,在配置文件中开启相应的注解处理器-->
    <!--这个元素的时候,还要指定对应的bean-->
    <context:annotation-config/>
    <!--分别定义三个Bean的实例-->
    <bean id="userDao" class="com.yzb.chapter02.example5.UserDaoImpl"></bean>
    <bean id="userService" class="com.yzb.chapter02.example5.UserServiceImpl"></bean>
    <bean id="userController" class="com.yzb.chapter02.example5.UserControllerImpl"></bean>





</beans>

bean6.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-4.3.xsd
      http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    <!--使用context命名空间,通知Spirng扫描指定包下的所有的Bean类,进行注解解析-->
    <context:component-scan base-package="com.yzb.chapter02.example5"></context:component-scan>
</beans>

Test6

package com.yzb.chapter02.example5;

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

public class Test6 {
    public static void main(String[] args) {
        //设置配置文件的路径
        String path = "com/yzb/chapter02/example5/bean6.xml";
        //加载配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
        UserController userController = (UserController) applicationContext.getBean("userController");
        userController.say();
    }
}

结果图

在这里插入图片描述

自动装配

  • 就是不适用context命名空间的方式,去完成装配,使用Spring中的元素中的autowire属性,
  • 自动装配就是将一个Bean自动的注入到其他Bean的property中
    @@@
  • autowire的五个值
  • default:根据的上一级标签的default-autowire属性值确定,
  • byname:根据属性的名称进行装配
  • byType:根据属性的数据类型进行装配,
  • constructor:根据构造函数参数的数据类型进行自动装配
  • no:在默认情况下,不适用自动装配。
    修改UserserviceImpl和UserControllerImpl文件,在文件中增加类属性的setter方法。

自动装配的配置文件模板

applicaitonContext.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-4.3.xsd
      http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-4.3.xsd">

</beans>

UserserviceImpl

package com.yzb.chapter02.example5;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service("userService")
public class UserServiceImpl implements UserService {
    @Resource(name="userDao")
    private UserDao userDao;
    @Override
    public void say() {
        userDao.say();
        System.out.println("userService ...save....");
    }
    public void setUserDao(UserDao userDao){
        this.userDao = userDao;
    }
}

UserControllerImpl

package com.yzb.chapter02.example5;

import org.springframework.stereotype.Controller;

import javax.annotation.Resource;

@Controller("userController")
public class UserControllerImpl implements UserController {
    @Resource(name = "userService")
    private UserService userService;

    @Override
    public void say() {
        userService.say();
        System.out.println("userController .... save.....");
    }
    public void setUserService(UserService userService){
        this.userService = userService;
    }
}

bean6.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-4.3.xsd
      http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    <!--使用bean元素的autowire进行自动装配-->
    <bean id="userDao" class="com.yzb.chapter02.example5.UserDaoImpl"></bean>
    <bean id="userService" class="com.yzb.chapter02.example5.UserServiceImpl" autowire="byName"></bean>
    <bean id="userController" class="com.yzb.chapter02.example5.UserControllerImpl" autowire="byName"></bean>
</beans>

对于byname的代码的理解

  • 在默认的情况下,通常使用ref来装配Bean,但设置了autowire="byName"后,Spring会对userServiceBean中的属性进行寻找,并将属性名称与配置文件中定义的Bean做匹配,由于UserServiceImpl中定义了UserDao的属性以及setter方法,这与配置文件中id为userDao的Bean相匹配的,所以Spring会自动将id为userDao的Bean装配到Id为userService的Bean中。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值