zoukankan      html  css  js  c++  java
  • spring-第七篇之深入理解容器中的bean

    1、抽象bean与子bean

          用于指定配置模板。

    2、容器中的工厂bean

          这种工厂bean必须实现FactoryBean接口,通过spring容器getBean()方法获取它时,容器返回的不是FactoryBean实现类的实例,而是返回FactoryBean的产品(即该工厂bean的getObject()方法的返回值,至于该方法返回什么东西,使我们重写该方法时决定的,一般是工厂bean生成的实例)。

          FactoryBean接口提供了3个方法:

            1》T getObject():实现该方法返回该工厂bean生成的java实例。

            2》Class<?> getObjectType():实现该方法返回该工厂bean生成的java实例的实现类。

            3》bolean isSingleton():实现该方法表示该工厂bean生成的java实例是否为单例模式。

          举一例子:

          GetFieldFactoryBean.java

    package com.lfy.bean;
    
    import java.lang.reflect.Field;
    
    import org.springframework.beans.factory.FactoryBean;
    
    public class GetFieldFactoryBean implements FactoryBean<Object> {
        
       private String targetClass;
       private String targetField;
       
       public void setTargetClass(String targetClass) {
           this.targetClass=targetClass;
       }
       
       public void setTargetField(String targetField) {
           this.targetField=targetField;
       }
       
       /**
        * 返回工厂bean所生产的产品
        */
       @Override
       public Object getObject() throws Exception{
           
           Class<?> clazz=Class.forName(targetClass);
           Field field=clazz.getField(targetField);
           return field.get(null);
       }
    
        /**
         * 获取工厂bean所生产的产品的类型
         */
        @Override
        public Class<? extends Object> getObjectType() {
            
            return Object.class;
        }
        
        /**
         * 返回该工厂bean所生产的产品是否为单例
         */
        @Override
        public boolean isSingleton() {
            
            return false;
        }
    }

         Cat.java

    package com.lfy.bean;
    
    public class Cat {
    
        //品种:猫
        public static final String variety="猫";
        
        //叫声:有可能是“喵喵”,也有可能是其他的
        public static String voice="喵喵";
    }

        Dog.java

    package com.lfy.bean;
    
    public class Dog {
    
        //品种:狗
        public static final String variety="狗";
        
        //叫声:有可能是“汪汪”,也有可能是其他的
        public static String voice="汪汪";
    }

         beans.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- spring配置文件的根元素,使用spring-beans-4.0.xsd语义约束 -->
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns="http://www.springframework.org/schema/beans"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
          
          <bean id="cat" class="com.lfy.bean.GetFieldFactoryBean">
             <property name="targetClass" value="com.lfy.bean.Cat"/>
             <property name="targetField" value="voice"/>
          </bean>
          
          <bean id="dog" class="com.lfy.bean.GetFieldFactoryBean">
             <property name="targetClass" value="com.lfy.bean.Dog"/>
             <property name="targetField" value="voice"/>
          </bean>
    </beans>

         SpringTest.java

    package com.lfy.main;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * 容器中的工厂bean
     * @author lfy
     *
     */
    public class SpringTest {
    
        public static void main(String[] args) {
            
            ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
            
            System.out.println(ctx.getBean("cat"));
            System.out.println(ctx.getBean("dog"));
            
            System.out.println(ctx.getBean("&dog"));
        }
    
    }

         运行结果:

        总结:spring容器会自动检测容器中的所有bean,如果发现某个bean实现类(如:GetFieldFactoryBean)实现了FactoryBean接口,spring容器就会在实例化该bean,根据<property.../>执行setter方法之后,额外调用该bean的getObject()方法,并将该方法的返回值作为容器中的bean。

        对于在ApplicationContext.getBean()方法使用&符号,将会得到FactoryBean本身,而不是它的产品。

    3、获取bean本身的部署id

        实现BeanNameAware接口,其中的方法setBeanName(String name)方法会在容器检查到目标bean实现了BeanNameAware接口的时候(目标bean已经实例化完成),自动调用该方法,并将目标bean部署时的id作为参数传入到该方法中。

        举个例子:

        

        Chinese.java

    package com.lfy.bean;
    
    import org.springframework.beans.factory.BeanNameAware;
    
    public class Chinese implements BeanNameAware {
    
        private String beanName;
        
        @Override
        public void setBeanName(String beanName) {
            
            this.beanName=beanName;
        }
        
        public void info() {
            
            System.out.println("Chinese实现类"+",部署该bean时指定的id为:"+beanName);
        }
    
    }

        beans.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- spring配置文件的根元素,使用spring-beans-4.0.xsd语义约束 -->
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns="http://www.springframework.org/schema/beans"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
          
          <bean id="chin" class="com.lfy.bean.Chinese"></bean>
    </beans>

         SpringTest.java

    package com.lfy.main;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.lfy.bean.Chinese;
    
    /**
     * 获得bean本身的id
     * @author lfy
     *
     */
    public class SpringTest {
    
        public static void main(String[] args) {
            
            ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
            
            Chinese chin=ctx.getBean("chin", Chinese.class);
            chin.info();
        }
    
    }

        运行结果:

     4、强制初始化bean

         某些时候需要被依赖bean先于目标bean初始化,可以使用depends-on属性,该属性可以强制初始化一个或者多个被依赖的bean。

  • 相关阅读:
    Windows下的SASS环境搭建
    cocos开发环境搭建
    cocos2d-x中描述精灵帧图片的plist和json文件各个key的含义
    seajs模块路径解析 简单总结
    【LESS系列】内置函数说明
    Zepto自定义模块打包构建
    【LESS系列】高级特性
    【LESS系列】三角形Mixins
    关于delete和对象复制
    vue使用技巧
  • 原文地址:https://www.cnblogs.com/ZeroMZ/p/11335661.html
Copyright © 2011-2022 走看看