基于xml的Bean的配置

基于xml的Bean的配置

在Spring中,Bean是指被Spring IOC容器管理的Java对象。在配置Bean时,我们可以通过XML配置文件或者注解的方式来告诉Spring容器应该如何创建和管理这些Bean。

  1. 配置Bean的id和class属性 在XML配置文件中,我们需要使用**<bean>**标签来配置Bean,其中最重要的是id和class属性。id属性用于指定Bean在容器中的名称,而class属性用于指定Bean的实现类。例如:
<bean id="userDao" class="com.congyun.dao.impl.UserDaoImpl">

这段配置的含义是,创建一个名为"userDao"的Bean,并将其实现类指定为"com.congyun.dao.impl.UserDaoImpl"。这样,在Spring容器启动时,就会根据这个配置信息创建一个UserDaoImpl对象,并将其放入Spring容器中

此时存储到Spring容器(singleObjects单例池)中的Bean的beanName是userDao,值是UserDaolmpl对象,可以根据beanName获取Bean实例

applicationContext.getBean ( "userDao" ) ;

如果不配置id,则Spring会把当前Bean实例的全限定名作为beanNa

applicationContext.getBean ( "com.congyun.dao.impl.UserDaoImpl");
  1. 配置Bean的作用域 在配置Bean时,我们可以通过scope属性来指定Bean的作用域。Spring支持以下5种作用域:
  • singleton:单例模式,一个容器只会创建一个Bean实例,默认值,每次getBean时都是从单例池中获取相同的Bean实例。
  • prototype:原型模式,每次从容器中获取Bean时都会创建一个新的实例,当调用getBean时才会实例化Bean,每次getBean都会创建一个新的Bean实例
  • request:请求作用域,每次HTTP请求都会创建一个新的Bean实例
  • session:会话作用域,每个HTTP会话都会创建一个新的Bean实例
  • 上述两组需要导入spring-webmvc
  • global session:全局会话作用域,通常用于Portlet应用中
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl" scope="prototype">

这样,每次从Spring容器中获取userService时,都会创建一个新的UserServiceImpl对象。

  1. 配置Bean的依赖关系 在Spring中,Bean之间可以存在依赖关系,即一个Bean依赖于另一个Bean。在配置Bean时,我们可以使用**<property>**标签或者构造函数注入的方式来定义Bean之间的依赖关系

    1. 使用<property>标签注入依赖 使用<property>标签注入依赖时,需要指定name属性和ref属性。其中name属性指定要注入的属性名称,ref属性指定要注入的Bean的id或者名称。

      例如,将userService中的userDao属性注入userDao Bean:

      <bean id="userService" class="com.congyun.service.impl.UserServiceImpl">
          <property name="userDao" ref="userDao"/>
      </bean>
      
    2. 使用构造函数注入依赖 使用构造函数注入依赖时,需要在标签中使用标签来指定构造函数参数的值或者Bean的引用。

      例如,将userService中的userDao属性通过构造函数注入:

      public class UserService {
          private UserDao userDao;
      
          public UserService(UserDao userDao) {
              this.userDao = userDao;
          }
      }
      <bean id="userDao" class="com.congyun.dao.impl.UserDaoImpl" />
      <bean id="userService" class="com.congyun.service.impl.UserServiceImpl">
          <constructor-arg ref="userDao" />
      </bean>
      
      
  2. Bean的别名配置:可以为当前Bean指定多个别名,根据别名也可以获得Bean对象

    <bean id="userDao" name="aaa,bbb" class=" com.congyun.dao.impl.UserDaoImpl"/>
    

    此时多个名称都可以获得UserDaolmpl实例对象

    applicationContext.getBean("userDao");
    applicationContext.getBean("aaa");
    applicationContext.getBean ("bbb");
    
  3. Bean的延迟加载
    当lazy-initi设置为true时为延迟加载,也就是当Spring容器创建的时候,不会立即创建Bean实例,等待用到时在创建Bean实例并存储到单例池中去,后续在使用该Bean直接从单例池获取即可,本质上该Bean还是单例的

    <bean id="userDao" class=" com.congyun.dao.impl.UserDaoImpl" lazy-init="true" />
    
  4. Bean的初始化和销毁方法配置
    Bean在被实例化后,可以执行指定的初始化方法完成一些初始化的操作
    Bean在销毁之前也可以执行指定的销毁
    方法完成一些操作,初始化方法名称和销毁方法名称通过

    <bean id="userDao" class="com.congyun.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy" / >
    
    public class UserDaoImpl implements UserDao {
    	public UserDaoImpl() { 
      		System.out.println ( "UserDaoImpl创建了..."); 
    	}
        public void init(){
            System.out.println ("初始化方法..."); 
        }
    	public void destroy(){ 
            System.out.println("销毁方法..."); 
        }
    }
    
    // 销毁函数的执行
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
    //        根据beanName获得容器中的Bean实例
            UserService userService = (UserService) applicationContext.getBean("userService");
            System.out.println(userService);
    
            UserService userService1 = (UserService) applicationContext.getBean("service");
            System.out.println(userService1);
            applicationContext.close();
    

    当一个Bean的作用域为prototype时,容器不会管理该Bean的生命周期,也就是不会调用该Bean的销毁方法(destroy-method)

    如果需要在一个prototype作用域的Bean销毁时执行特定的逻辑,可以通过在该Bean的使用方手动调用销毁方法来实现。比如在使用该Bean的方法或者类中,在不需要该Bean实例时手动调用销毁方法。

    另外,需要注意的是,对于prototype作用域的Bean,Spring容器只会在创建该Bean实例时执行一次init-method方法,而不会在每次获取Bean实例时都执行。因此,在prototype作用域下,init-method方法只会在Bean实例创建时执行一次,而destroy-method方法则需要手动调用。

    扩展:除此之外,我们还可以通过实现 InitializingBean接口,完成一些Bean的初始化操作,如下:

    public class UserDaoImpl implements UserDao,InitializingBean {
    	public UserDaoImpl () {
            System.out.println ( "UserDaoImpl创建了...");
        }
        public void init () {
            System.out.println("初始化方法..." );
        }
    	public void destroy () {
            System.out.println("销毁方法...");
        }//执行时机早于init-method配置的方法
    	public void afterPropertiesSet ( ) throws Exception {
    		System.out.println ( " InitializingBean. . . " ) ;
        }
        // PS:afterPropertiesSet和初始化方法均需要在实例的属性值设置完之后才去执行
    
  5. Bean的实例化配置
    Spring的实例化方式主要如下两种:

    1. 构造方式实例化:底层通过构造方法对Bean进行实例化
        <bean id="userService" class="com.congyun.service.impl.UserServiceImpl" init-method="init" destroy-method="destroy" scope="prototype" name="service">
            <!--依赖注入-->
            <constructor-arg name="name" value="congyun"></constructor-arg>
            <property name="userDao" ref="userDao"/>
        </bean>
        在写了<constructor-arg name="name" value="congyun"></constructor-arg>后自动执行有参构造,去掉则执行无参构造
    
    1. 工厂方式实例化:底层通过调用自定义的工厂方法对Bean进行实例化

      1. 静态工厂方法实例化Bean——通过这种方法可以在Bean创建之间执行一些其他的逻辑操作
          @Test
      //    Static factory
          public void staticFactory(){
              ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
              UserService userService = (UserService) applicationContext.getBean("userServiceOne");
              System.out.println(userService);
          }
      
      package com.congyun.factory;
      import com.congyun.service.UserService;
      import com.congyun.service.impl.UserServiceImpl;
      
      public class staticFactory {
          public static UserService userService(){
              return new UserServiceImpl();
          }
      }
      
      <bean id="userServiceOne" class="com.congyun.factory.staticFactory" factory-method="userService">
      
          </bean>
      
      1. 实例工厂方法实例化Bean——通过这种方法可以在Bean创建之间执行一些其他的逻辑操作
          @Test
      //    beanUserService
          public void beanUserService(){
              ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
              UserService userService = (UserService) applicationContext.getBean("beanUserService");
              System.out.println(userService);
          }
      
      public class beanFactory {
      
          public UserService userService(){
              return new UserServiceImpl();
          }
      }
      
          <bean id="beanFactory" class="com.congyun.factory.beanFactory">
      
          </bean>
          <bean id="beanUserService" factory-bean="beanFactory" factory-method="userService" scope="prototype">
      
          </bean>
      
      1. 实现FactoryBean规范延迟实例化Bean
          @Test
          public void factoryBean(){
              ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
              UserService userService = (UserService) app.getBean("factoryBean");
              UserService userService1 = (UserService) app.getBean("factoryBean");
              System.out.println(userService);
              System.out.println(userService1);
              // 两者输出结果一直的原因:均是从FactoryBeanObjectCache中获取的数据,当设置为prototype,FactoryBeanObjectCache的值为NULL
          }
      public class beanFactory {
      
          public UserService userService(){
              return new UserServiceImpl();
          }
      }
      
          <bean id="factoryBean" class="com.congyun.factory.factoryBean">
      
          </bean>
      
  6. bean的注入方式

    注入方式配置方式
    通过Bean的set方法注入<property name=“userDao” ref=“userDao” />
    <property name=“userDao” value=“haohao”/>
    通过构造Bean的方法进行注入<constructor-arg name=“name” ref=“userDao”/>
    <constructor-arg name=“name” value=“haohao”/>

    依赖注入的数据类型有如下三种:

    1. 普通数据类型,例如: String.int、boolean等,通过value属性指定
    2. 引用数据类型,例如: UserDaolmpl、DataSource等,通过ref属性指定
    3. 集合数据类型,例如:List、Map、Properties等
    @Test
    public void ListTest(){
    	ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
    	UserService userService = (UserService) app.getBean("userService");
    	System.out.println(userService);
    }
    public class UserServiceImpl implements UserService {
        List<String> myString;
    
        public void setMyString(List<String> myString) {
            this.myString = myString;
            getMyString();
        }
    
        public List<String> getMyString() {
            for (int i =0; i < myString.size();i++)
                System.out.println(myString.get(i));
            return myString;
        }
    	public List<UserDaoImpl> setUserDao(List<UserDaoImpl> userDao) {
            this.userDao = userDao;
            return userDao;
        }
    }
    <!--配置UserServiceImpl-->
    <bean id="userService" class="com.congyun.service.impl.UserServiceImpl">
    	<property name="myString">
    		<list>
    			<value>test</value>
    			<value>test1</value>
    			<value>test2</value>
    			<value>test3</value>
    		</list>
    	</property>
    	<property name="userDao">
    		<list>
    			<ref bean="userDao"></ref>
    			<ref bean="userDao"></ref>
    			<ref bean="userDao"></ref>
        // 在外部创建多个不同的userDao
    		</list>
    	</property>
    </bean>
    

    自动装配:如果被注入的属性类型是Bean引用的话,那么可以在**<bean>标签中使用autowire属性去配置自动注入方式**,属性值有两个:

    1. byName:通过属性名自动装配,即去匹配 setXxx 与id=“xxx” (name=“xxx”)是否一致
    2. byType:通过Bean的类型从容器中匹配,匹配出多个相同Bean类型时,报错。
    <bean id="userService" class="com.itheima.service.imp1.UserServiceImpl"autowire="byType">
    
  7. Spring的其他配置标签

    Spring的xml标签大体上分为两类,一种是默认标签,一种是自定义标签

    1. 默认标签:就是不用额外导入其他命名空间约束的标签,例如<bean>标签
    2. 自定义标签:就是需要额外引入其他命名空间约束,并通过前缀引用的标签,例如**<context.property-placeholder/>**标签
    标签作用
    <beans>一般作为xml配置根标签,其他标签都是该标签的子标签
    <bean>Bean的配置标签,上面已经详解了,此处不再阐述
    <import>外部资源导入标签
    <alias>指定Bean的别名标签,使用较少

    <beans>标签,除了经常用的做为根标签外,还可以嵌套在根标签内,使用profile属性切换开发环境

    <bean></bean>
    <!-―配置测试环境下,需要加载的Bean实例-->
    <beans profi1c="test">
    </beans>
    <!-―配置开发环境下,需要加载的Bean实例-->
    <beans profi1e="dev" >
    </beans>
    

    可以使用以下两种方式指定被激活的环境:

    1. 使用命令行动态参数,虚拟机参数位置加载**-Dspring.profiles.active=test**
    2. 使用代码的方式设置环境变量:在执行相关代码之前添加System.setProperty(“spring.profiles.active” ,“test”)

    此时公共部分的bean和指定激活的环境生效

    **<import>**标签,用于导入其他配置文件,项目变大后,项目变大后,就会导致一个配置文件内容过多,可以将一个配置文件根据业务某块进行拆分,拆分后,最终通过<import>标签导入到一个主配置文件中,项目加载主配置文件就连同导入的文件一并加载了

    <!--导入用户模块配置文件-->
    <import resource="classpath:UserModuleApplicationcontext.xml"/>
    <!--导入商品模块配置文件-->
    <import resource="classpath:ProductModuleApplicationcontext.xml" />
    

    Spring的自定义标签需要引入外部的命名空间,并为外部的命名空间指定前缀,使用**<前缀:标签>**形式的标签,称之为自定义标签,自定义标签的解析流程也是Spring xml扩展点方式之一

    // 这个部分的内容根据标签名称自己在网上查找
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
    <!--默认标签-->
    <bean id="userDao" class="com.congyun.dao.imp1.UserDaoImpl" />
    <!--自定义标签-->
    <context:property-placeholder/>
    <mvc:annotation-driven/>
    <dubbo:application name="application"/>
    
Xml配置方式功能描述
<bean id=“” class=“”>Bean的id和全限定名配置
<bean name=“”>通过name设置Bean的别名,通过别名也能直接获取到Bean实例
<bean scope=“”>Bean的作用范围,BeanFactory作为容器时取值singleton和prototype
<bean lazy-init=“”>Bean的实例化时机,是否延迟加载。BeanFactory作为容器时无效
<bean init-method=“”>Bean实例化后自动执行的初始化方法,method指定方法名
<bean destroy-method=“”">Bean实例销毁前的方法,method指定方法名
<bean autowire=“byType”>设置自动注入模式,常用的有按照类型byType,按照名字byName
<bean factory-bean=“” factory-method=“”/>指定哪个工厂Bean的哪个方法完成Bean的创建
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值