栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot 扩展机制 ——Spring.factories文件 如何将外部项目加入Spring容器

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot 扩展机制 ——Spring.factories文件 如何将外部项目加入Spring容器

SpringBoot 扩展机制 ——Spring.factories文件 如何将外部项目加入Spring容器 ▶ 简介 简单说用于模块之间解耦,外部项目下各种配置、类加入到Spring容器中进行管理,类似JAVA中SPI机制。机制自行百度。 ▶ 方式 将外部类引入IOC容器两种方式 1.@import 2.加入Spring.factories文件 — 主讲这个 ▶ Spring.factories文件 1.在resource目录下 meta-INF/ Spring.factories 文件 2.格式:自定义需要扫描到类(接口),多个用 ”,“ 隔开 3.SpringFactoriesLoader类会去扫描加载文件下定义类,加入容器
	org.springframework.boot.autoconfigure.EnableAutoConfiguration=
  	com.mostsnails.common.base.utils.config.WebLogAutoConfiguration,
  	com.mostsnails.common.base.utils.config.RedisAutoConfiguration,
  	com.mostsnails.common.base.utils.test.TestClass
注意这里使用EnableAutoConfiguration ,SpringBoot启动类@SpringBootApplication注解包下有@EnableAutoConfiguration和@Component 具体作用开启自动装备,将满足条件@Configuration配置加入到SpringBoot中。 Spring.factories也可以包含其他类型
	# Initializers
org.springframework.context.ApplicationContextInitializer=
org.springframework.boot.autoconfigure.SharedmetadataReaderFactoryContextInitializer,
org.springframework.boot.autoconfigure.logging.ConditionevaluationReportLoggingListener

# Application Listeners
org.springframework.context.ApplicationListener=
org.springframework.boot.autoconfigure.BackgroundPreinitializer
	....
可以去看项目下spring-boot-***-start jar包 外部项目下Redis配置类
@Configurable
public class RedisAutoConfiguration {
    private static org.slf4j.Logger log = LoggerFactory.getLogger(RedisAutoConfiguration.class);

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        // 创建RedisTemplate对象
        RedisTemplate template = new RedisTemplate<>();
        // 配置连接工厂
        template.setConnectionFactory(factory);
        // 定义Jackson2JsonRedisSerializer序列化对象
        Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会报异常
        om.activateDefaultTyping(LaissezFaireSubTypevalidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        jacksonSeial.setObjectMapper(om);
        StringRedisSerializer stringSerial = new StringRedisSerializer();
        // redis key 序列化方式使用stringSerial
        template.setKeySerializer(stringSerial);
        // redis value 序列化方式使用jackson
        template.setValueSerializer(jacksonSeial);
        // redis hash key 序列化方式使用stringSerial
        template.setHashKeySerializer(stringSerial);
        // redis hash value 序列化方式使用jackson
        template.setHashValueSerializer(jacksonSeial);
        template.afterPropertiesSet();
        return template;
    }

    
    @Bean
    public CacheManager cacheManager(RedisTemplate template) {
        RedisCacheConfiguration defaultCacheConfiguration =
                RedisCacheConfiguration
                        .defaultCacheConfig()
                        // 设置key为String
                      .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getStringSerializer()))
                        // 设置value 为自动转Json的Object
                        .serializevaluesWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getValueSerializer()))
                        // 不缓存null
                        .disableCachingNullValues()
                        // 缓存数据保存1小时
                        .entryTtl(Duration.ofHours(1));
        RedisCacheManager redisCacheManager =
                RedisCacheManager.RedisCacheManagerBuilder
                        // Redis 连接工厂
                        .fromConnectionFactory(template.getConnectionFactory())
                        // 缓存配置
                        .cacheDefaults(defaultCacheConfiguration)
                        // 配置同步修改或删除 put/evict
                        .transactionAware()
                        .build();
        return redisCacheManager;
    }

    @Bean
    public RedisUtils redisUtils(StringRedisTemplate stringRedisTemplate) {
        log.info("Redis工具类.....Start");
        return new RedisUtils(stringRedisTemplate);
    }
}
 

▶ 延伸扩展 — 选择性加载@Conditional 和 @ConditionalOn*** 在一些自动装配配置类中 出现过 @ConditionalOn***,@EnableAutoConfiguration会在满足条件情况下加入IOC容器
public class WebLogAutoConfiguration {
    private static org.slf4j.Logger log = LoggerFactory.getLogger(WebLogAutoConfiguration.class);

    public WebLogAutoConfiguration() {
        log.info("Web日志记录配置类.....Start");
    }

    @Bean
    @ConditionalOnWebApplication//当项目是一个Web项目时进行实例化
    @ConditionalOnMissingBean(WebLogAspect.class)//当容器里没有指定Bean的条件下进行实例化。
    public WebLogAspect webLogAspect() {
        log.info("注入webLogAspect类.....");
        return new WebLogAspect();
    }
}
▶ 更多@Conditional 注解
@ConditionalOnBean:		仅仅在当前上下文中存在某个对象时,才会实例化一个Bean。
@ConditionalOnClass:	某个class位于类路径上,才会实例化一个Bean。
@ConditionalOnexpression:当表达式为true的时候,才会实例化一个Bean。
@ConditionalOnMissingBean:仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean。
@ConditionalOnMissingClass:某个class类路径上不存在的时候,才会实例化一个Bean。
@ConditionalOnNotWebApplication:不是web应用,才会实例化一个Bean。
@ConditionalOnBean:		当容器中有指定Bean的条件下进行实例化。
@ConditionalOnMissingBean:当容器里没有指定Bean的条件下进行实例化。
@ConditionalOnClass:	当classpath类路径下有指定类的条件下进行实例化。
@ConditionalOnMissingClass:当类路径下没有指定类的条件下进行实例化。
@ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。
@ConditionalOnNotWebApplication:当项目不是一个Web项目时进行实例化。
@ConditionalOnProperty:	当指定的属性有指定的值时进行实例化。
@ConditionalOnexpression:	基于SpEL表达式的条件判断。
@ConditionalOnJava:	当JVM版本为指定的版本范围时触发实例化。
@ConditionalOnResource:	当类路径下有指定的资源时触发实例化。
@ConditionalOnJndi:	在JNDI存在的条件下触发实例化。
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化。

▶ 如何使用IOC容器对象 1.@Autowired 2.ApplicationContext
@RunWith(SpringRunner.class)
@SpringBootTest(classes = WebDemoApplication.class)
public class JunitTest {
//    @Autowired
//    private TestClass testClass;

    @Test
    public void customYAMLTest(){
        TestClass bean = BeanFactoryUtil.getBean(TestClass.class);
        System.out.println(JSON.toJSonString(bean));
    }
}
BeanFactoryUtil
public class BeanFactoryUtil {
    private static ApplicationContext context;

    public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (context == null){
            context = applicationContext;
        }
    }
    // 获取applicationContext
    private static ApplicationContext getApplicationContext() {
        return context;
    }

    // 通过name获取Bean
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    // 通过class获取Bean
    public static  T getBean(Class clazz) {
        return getApplicationContext().getBean(clazz);
    }

    // 通过name,以及Clazz返回指定的Bean
    public static  T getBean(String name, Class clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号