• Spring中的Bean


     一、Bean的配置

    1.Spring可以被看做是一个大型的工厂,这个工厂的作用就是生产和管理Spring中的Bean,要在项目中使用这个工厂,就要对Spring的配置文件进行配置。Spring支持XML和Properties两种方式的配置文件。在实际开发过程中,最常用的就是XML各式的配置,这种配置方式是通过XML文件来注册并管理Bean之间的依赖关系。

    2.在Spring中,XML配置文件的根元素是<beans>,<beans>中包含了多个<bean>子元素,每个<bean>子元素定义了一个Bean,并描述了该Bean如何被装配到Spring容器中。Bean中同样包含很多个属性以及子元素。

    在配置文件中,通常一个普通的Bean只需要定义id和class属性即可。

    二、Bean的实例化

    1.在面向对象程序中,想要使用某个对象,就需要先实例化这个对象。同样的在Spring中想要使用容器中的Bean,同样需要实例化Bean。

    实例化Bean有三种方式,分别是构造器实例化、静态工厂实例化和实例工厂实例化。下面就这三种实例化的方式进行详细的解释。

    2.构造器实例化

    构造器实例化是指Spring容器通过Bean对应的类中默认的无参构造方法来实例化Bean。

    (1)在com.cisco.instance.contructor包中,创建Bean1类。

    public class Bean1{
    }

    (2)创建beans.xml的配置文件,在配置文件中创建一个id为bean1的Bean,并用class属性指定其对应的实现类为Bean1。

    <bean id="bean1" class="com.cisco.instance.constructor.Bean1"/>

    (3)创建测试类IntanceTest1,来测试构造器是否能够实例化Bean。定义配置文件的路径,然后Spring容器会通过id为beab1的实现类Bean1中的默认无参构造方法对Bean进行实例化。

    public class InstanceTest1{
          public static void main(){
          //1.定义配置文件的路径,使用容器加载文件 ApplicationContext ac
    = new ClassPathApplicatiobContext("beans.xml");       //2.加载配置文件,对Bean进行实例化
    Bean1 bean1
    = (Bean1)ac.getBean("bean1"); System.out.println(bean1); } }

    3.静态工厂方式实例化

    该方法要求开发者创建一个惊天工厂的方法来创建Bean的实例,其中Bean配置中的class属性所指定的不再是Bean的实现类,而是静态工厂类,同时还需要使用factory-method属性来指定所创建的静态工厂方法。

    (1)创建MyBeanFactory类,并在类中创建一个静态方法createBean()来返回Bean2实例。如下所示的代码:

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

    (2)创建beans2.xml

    <bean id="bean" class="com.cisco.instance.static_factory.Mybean2Factory"  factory-method="createBean"   />

    在上述的配置文件中,首先通过<bean>元素的id属性定义了一个名称为bean2的Bean,由于使用的是静态工厂方法,所以需要通过class属性指定其对应的其工厂实现类为MyBeanFactory,这种方式配置Bean之后,需要指定factory-method属性来指定工厂容器的属性,其方法名称为createBean

    (3)创建测试类来测试静态工厂方是否能够实例化Bean。

    public class InstanceTest2{
          public static void main(String[] args){
              ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
              System.out.println(applicationContext.getBean("bean2"));
          }
    }

    4工厂方法实例化。使用实例工厂方式来进行实例化,在工厂类中不再使用静态方法创建Bean实例,而是采用直接创建Bean的形式。同时在配置文件中,需要实例化的bean也不是通过class属性直接指向实例化类,而是通过factory-bean属性指向配置的实例工厂中的哪个方法。

    (1)创建工厂类MyBeanFactory,在类中使用默认无参构造方法输出某些语句。

    public class BeanFactory{
           public BeanFactory(){
             System.out.println("bean3工厂中的实例化");
           }
           //创建Bean3实例的方法
           public Bean createBean(){
              return new Bean();
           }
    }

    (2)beans.xml配置

    <!--配置工厂-->
    <bean id="myBeanFactory"   class="com.cisco.instance.factory.MyBeanFactory"/>
    <bean id ="bean3" factory-bean="myBeanFactory"  factory-method="createBean"/>

    上述配置中,首先配置一个工厂Bean,然后配置了需要实例化的Bean,id为bean3的bean中,将factory-bean属性指向实例化工厂,该属性的值就是工厂bean的id,使用factory-method属性确定使用工厂中的createBean()方法。

    三、Bean的作用域

    1.作用域的种类

    (1)Singleton作用域。Singleton是Spring容器的默认作用域,当Bean的作用域为Singleton的时候,Spring容器只会存在一个共享的实例,并且所有对Bean的请求,只要id与该Bean的id相匹配,就会返回一个Bean实例,Singleton对于无会话状态的Bean来说是最理想的。在Spring配置文件中,Bean的作用域是通过<bean>元素的scope属性来指定的。

     (2)Prototype作用域。对于需要保持回话状态的Bean,应该使用prototype作用域。在使用Prototype作用域的时候,Sring容器会为每个对该Bean的请求都创建一个新的实例。

    四、Bean的生命周期

    1.对于prototype作用域的Bean,Spring只负责创建,当容器创建了Bean之后,Bean的实例就交给客户端代码来进行管理,Spring容器将不再跟踪其生命周期。

    五、Bean的装配方式

    1.Bean装配可以理解为依赖注入,Bean的装配方式即Bean的依赖注入的方式。Spring容器支持多种形式的Bean的装配方式,如基于XML的装配、基于注解的装配和自动装配等,其中使用最多的就是基于注解的装配方式。

    2.基于XML的装配方式。

    (1)Spring提供两种基于XML的装配方式:设值注入和构造注入。在Spring实例化Bean的过程中,Spring首先会调用Bean的默认构造方法来实例化Bean对象,然后通过反射的方式来调用setter方法注入属性值。因此设值注入要求Bean必须满足下面的两点要求:Bean类必须提供 一个默认的无参构造函数;Bean类必须为注入的属性提供对应的setter方法。同时在配置文件中,需要使用<bean>元素的子元素<property>来为每个属性注入值,而在使用构造函数注入的时候,需要使用<bean>的子元素<constructor-arg>来定义构造方法的参数,可以使用其value属性来设置该参数的值。其属性index表示从0开始,value属性用于表示设置注入的值,其子元素<list>来为User类中对应的list集合属性注入指,然后又使用了设值注入的方式装配User类的实例,其中<property>元素用于调用Bean实例中setter方法完成属性赋值,从而完成依赖注入,而其子元素<list>同样是为User类中对应的list集合属性注入值。

    (2)基于Annnotation的装配

    Component:可以使用此注解描述Spring中的Bean,但是它是一个泛化的概念,仅仅表示一个组件,并且可以用于任何层次,使用这个注解的时候,只要将注解标注在相应的类上面即可。

    Repository:用于将数据访问层(DAO层)的类标识为Spring中的Bean,其功能与Component类似。

    Service:通常作用咋业务层上,用于将业务层的类标识为Spring中的Bean,其功能与Component相同。

    Controller:通常作用在控制层(SpringMVC的Controller),用于将控制层的类标识为Spring中的Bean,其功能与Component的功能相同。

    Autowired:用于对Bean的属性变量、属性的setter方法及构造方法进行标注,配合对应的注解处理器完成Bea的配置工作。

    Resource:其作用和Autowired一样。其区别在于@Autowired默认按照Bean类型进行装配,而Resource按照实例名称进行装配,@Resource中有两个重要的属性:name和type。Spring将name属性解析为Bean实例名称,type解析为Bean的实例类型,如果指定name属性,则按照实例名称进行装配,如果指定type类型,则按照Bean的类型进行装配;如果都不进行指定,则先按照Bean的实例名称进行装配,如果不能够进行匹配,则再按照Bean的类型进行匹配;如果都无法进行匹配,则抛出NoSuchBeanDefinitionException异常。

    Qualifier:与Autowired注解配合使用,会将默认按照Bean的类型装配修改为按照Bean的名称进行装配,Bean的实例名称有Qualifer注解的参数指定。

    (3)案例演示

    dao层

    package com.cisco.annotation;
    
    public interface UserDao {
        public void save();
    }
    
    
    package com.cisco.annotation.impl;
    
    import com.cisco.annotation.UserDao;
    import org.springframework.stereotype.Repository;
    
    /**
     * 在这里首先使用@Repository注解将UserDaoIml类标识为Spring中的Bean,
     * 其写法相当于<bean id= "userDao" class="com.cisco.annotation.impl.UserDao的编写"/>
     */
    @Repository("userDao")
    public class UserDaoImpl implements UserDao {
        public void save() {
            System.out.println("userDao save");
        }
    }

    Service层

    package com.cisco.annotation;
    
    public interface UserService {
        public void save();
    }
    
    package com.cisco.annotation.impl;
    
    import com.cisco.annotation.UserDao;
    import com.cisco.annotation.UserService;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    
    @Service("userService")
    public class UserServiceImpl implements UserService {
        //@Resource默认按照Bean的实例名称进行装配
        @Resource(name = "userDao")
        private UserDao userDao;
    
        /**
         * 这里首先使用@Service注解将UserServiceImpl类标识为Spring中的Bean,
         * 这个相当于<bean id="userService" class = "com.cisco.annotation.UserServiceImpl"/>
         * 然后使用@Resourcez注解标注在userDao属性上,这相当于在配置文件中<property name="userDao" ref = "userDao"/>
         *
         */
        public void save() {
            userDao.save();
            System.out.println("userServicec......save........");
        }
    }

    Controller层

    package com.cisco.annotation;
    
    import org.springframework.stereotype.Controller;
    
    import javax.annotation.Resource;
    
    /**
     * 在这个类中,@Controller注解标注了UserController类
     *
     * @Resource(name = "userService")<====><property name="userService" ref = "userService">
     *
     */
    @Controller("userController")
    public class UserController {
        @Resource(name = "userService")
        private UserService userService;
        public void save(){
            userService.save();
            System.out.println("userController save ");
        }
    
    }
  • 相关阅读:
    .NET中常用获取程序根目录的方法
    多态的实现
    9个优秀网上免费标签云生成工具
    Asp.Net自定义错误页心得介绍
    C# string.Format 格式化使用说明
    接口编程,反射创建对象
    DllImport使用的一点整理
    System.Data.ConstraintException: 未能启用约束。一行或多行中包含违反非空、唯一或外键约束的值。
    C# OleDb读取Excel文件 避免出现 科学计数法 的列
    C++翻译C#
  • 原文地址:https://www.cnblogs.com/bigdata-stone/p/10899718.html
Copyright © 2020-2023  润新知