2.spring中注册bean的几个组件(conditional,import,beanfactory)

一.conditional

Spring4提供了一个更通用的基于条件的Bean的创建,即使用@Conditional注解。

@Conditional根据满足某一个特定条件创建一个特定的Bean。

实现方式:自定义一个类实现org.springframework.context.annotation.Condition接口,在其matches方法中写自己的校验方式

package com.wuml.component.conditional;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

/**
 * @author by wml on 2019/10/17.
 */
public class SystemCondition implements Condition {

    /**
     * 采用网上较为普遍的配置 判定当前运行环境的系统是否是windows
     * @param context
     * @param metadata
     * @return
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String property = context.getEnvironment().getProperty("os.name");
        System.out.println("运行环境:"+property.toUpperCase());
        if(property.toUpperCase().contains("WINDOWS")){
            return true;
        }
        return false;
    }
}
package com.wuml.component.conditional;

import com.wuml.component.bean.Worker;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

/**
 * @author by wml on 2019/10/17.
 */
@Configuration
public class ConditionConfig {

    @Bean
    @Conditional({SystemCondition.class})
    public Worker worker(){
        Worker worker = new Worker();
        worker.setName("wuml");
        worker.setAge("18");
        return worker;
    }
}
package com.wuml.component.conditional;

import com.wuml.component.bean.Worker;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author by wml on 2019/10/17.
 */
public class ConditionMainTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ConditionConfig.class);
        Worker bean = annotationConfigApplicationContext.getBean(Worker.class);
        System.out.println(bean);
    }
}

测试结果

测试LINUX环境的话,我采用的是idea,对main方法设置VM options: -Dos.name=LINUX

此时运行就会出现没有这个bean定义

然后把代码中的WINDOWS改成LINUX

if(property.toUpperCase().contains("LINUX")){
            return true;
        }

再执行

二.import

根据import的组件注解源码中可以看到,它的value支持多种class设置进行注册bean

public @interface Import {

	/**
	 * {@link Configuration @Configuration}, {@link ImportSelector},
	 * {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
	 */
	Class<?>[] value();

}

1.手动添加组件到IOC容器;

2.实现ImportSelector接口

package com.wuml.component.imports;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @author by wml on 2019/10/17.
 */
public class ImporterSelector implements ImportSelector {
    /**
     * Select and return the names of which class(es) should be imported
     * @param importingClassMetadata
     * @return
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.wuml.component.imports.ImportWater"};
    }
}

3.实现ImportBeanDefinitionRegistrar(java8中引入了default关键字,在接口内部包含了一些默认的方法实现,在实现这个类的时候需要手动去看下需要实现的方法,编辑器不会提示需要实现的方法)

package com.wuml.component.imports;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @author by wml on 2019/10/17.
 */
public class ImportBeanDef implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean importWater = registry.containsBeanDefinition("com.wuml.component.imports.ImportWater");
        if(importWater){
            System.out.println("有水----------加载鱼");
            //有水才有鱼
            registry.registerBeanDefinition("importFish",new RootBeanDefinition(ImportFish.class));
        }
    }
}

配置类:

package com.wuml.component.imports;

import com.wuml.component.bean.Worker;
import com.wuml.component.factorybean.FactoryBeanDolphin;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @author by wml on 2019/10/17.
 */
@Configuration
/**
 * @link Configuration @Configuration}, {@link ImportSelector},
 * {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.**/
//Worker.class自定义注册,ImporterSelector.class实现ImportSelector接口,ImportBeanDef实现ImportBeanDefinitionRegistrar
@Import({Worker.class,ImporterSelector.class,ImportBeanDef.class})
public class ImportConfig {

}

测试类:

package com.wuml.component.imports;

import com.wuml.component.bean.Worker;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author by wml on 2019/10/17.
 */
public class ImportMainTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ImportConfig.class);
        String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
        for(String str:beanDefinitionNames){
            System.out.println(str);
        }
        Worker bean = annotationConfigApplicationContext.getBean(Worker.class);
        bean.setName("999");
        bean.setAge("1");
        System.out.println(bean);
        ImportWater importWater = annotationConfigApplicationContext.getBean(ImportWater.class);
        importWater.setName("888");
        importWater.setAge("2");
        System.out.println(importWater);
        ImportFish importFish = annotationConfigApplicationContext.getBean(ImportFish.class);
        importFish.setName("777");
        importFish.setAge("3");
        System.out.println(importFish);

    }
}

测试结果:

通过以上3种方式注册的worker,importWater,importFish都注册成功

3.Factorybean

BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。

Factorybean和ApplicationContext的区别:

ApplicationContext接口,它由BeanFactory接口派生而来,ApplicationContext包含BeanFactory的所有功能,ApplicationContext还提供了国际化处理、事件传递、Bean自动装配、各种不同应用层的Context实现;通常建议比BeanFactory优先

Factorybean和BeanFactory的区别(简单查阅了一下资料,此处简述):

BeanFactory是IOC最基本的容器,负责生产和管理bean,它为其他具体的IOC容器提供了最基本的规范

平时使用最多的2中applicationContext(ClassPathXmlApplicationContext,AnnotationConfigApplicationContext)都是实现了BeanFactory。

FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。

注:要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&

package com.wuml.component.factorybean;

import lombok.Data;

/**
 * @author by wml on 2019/10/17.
 */
@Data
public class Dolphin {
    String name;
    String age;
    public Dolphin(){

    }

    public Dolphin(String name,String age){
        this.age = age;
        this.name = name;
    }
}
package com.wuml.component.factorybean;

import org.springframework.beans.factory.FactoryBean;

/**
 * @author by wml on 2019/10/17.
 */
public class FactoryBeanDolphin implements FactoryBean<Dolphin> {

    @Override
    public Dolphin getObject() throws Exception {
        return new Dolphin("10","10");
    }

    @Override
    public Class<?> getObjectType() {
        return Dolphin.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}
package com.wuml.component.factorybean;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author by wml on 2019/10/17.
 */
@Configuration
public class BeanConfig {

    @Bean("factoryBeanDolphin")
    public FactoryBeanDolphin get(){
        return new FactoryBeanDolphin();
    }
}
package com.wuml.component.factorybean;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author by wml on 2019/10/17.
 */
public class MainTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);

        Dolphin bean = (Dolphin)annotationConfigApplicationContext.getBean("factoryBeanDolphin");
        System.out.println(bean);
        System.out.println(bean.getClass().getName());
        Object factoryBeanDolphin = annotationConfigApplicationContext.getBean("&factoryBeanDolphin");
        System.out.println(factoryBeanDolphin.getClass().getName());



    }
}


运行结果:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值