springboot详解--配置类与自动配置

文章目录

  • xml配置与javaconfig的对比
    • 1. 基于表达成面:
    • 2. 注册bean定义成面
    • 3. 表达依赖注入关系层面
  • javaconfig配置类的几种实现方式
  • 自动配置
  • FAQ

xml配置与javaconfig的对比

1. 基于表达成面:

  • 基于xml的配置:


    

  • 基于javaConfig的配置如下:
@Configration
public class MyConfig{
	//bean定义
}

任何标注了@Configration的java类定义都是一个JavaConfig配置类

2. 注册bean定义成面

  • 基于xml的配置:
    >
        <!-- 通过构造方法设置属性值 -->
    
  • 基于javaConfig的配置如下:

@Configration
public class MyConfig{
    @bean
    public MockService mockService(){
        return new MockService();
    }
}

任何一个标注了@bean的方法,器返回值将作为一个bean定义注册到Spring的IoC容器中,方法名默认为该bean的id。

3. 表达依赖注入关系层面

为了表达bean与bean之间的依赖关系,

  • 基于xml配置是这样实现的:
    
        
    
    
    
  • 基于javaconfig中是这样做的:
@Configration
public class MyConfig{
    @Bean
    public MockService mockService(){
        return new MockService(dependencyService());
    }
    @bean
    public DependencyService dependencyService(){
        return new DependencyService ();
    }
}

如果一个bean的定义依赖于其他bean,则直接调用对应javaconfig类中依赖bean的创建方法就可以了。
注意使用javaconfig创建多个同一类型的对象实例时,依赖注入的都是同一个Singleton的对象实例。Spring官方文档中说是通过拦截配置类的方法来避免多次初始化同一类型对象的问题,
一旦拥有拦截逻辑的子类发现当前方法没有对应的类型实例时才会去请求父类的同一方法来初始化对象实例,否则直接返回之前的对象实例。

javaconfig配置类的几种实现方式

springboot的配置类最常见的就是在类上面标注@Configuration,表示这是一个配置类(就是以前的xml);
实现配置类的具体实现方式如下:

  1. 在配置类的里面就有很多的@Bean标注的方法(就是以前的),方法名是id,方法返回值是class;
  2. 第一种扩充:标注了@Bean的方法里面返回值匿名内部类的形式
  3. 在配置类里面还写个静态内部类,静态内部类里面也有@Bean以及一些重写的方法。
  4. 配置类继承某个类,重写了父类方法

只要是想添加组件,你自定义的@Bean,可以放在任意的配置类中(标了@Configuration注解,或者写在有main方法的主配置类中)

配置类用的比较多的就是这几种,还有一些其他的可以自己多查查资料,或者分析一下源码。

首先这种直接加@Bean的方式就不说了,先说说第三种(这种常用啊),再说说第一种的扩充。第二种就不说了,我们现阶段用不到,不过看springboot自动配置类里面大量用到这种方式,所以这就导致了springboot就那几十个自动配置类,就几乎配置了web应用所有组件。

自动配置

核心:约定大于配置
springboot中提供了很多配置类供使用,***AutoConfigration.java,通过这些自动配置类,可以很简单的帮助我们使用某些功能,一般自动配置类中都集成了默认的配置。
自动配置类的幕后英雄:SpringFactoriesLoader
主要是从指定的配置文件META-INF/spring.factories(在springboot的jar包中)中加载配置,key-value的形式

在开发过程中如果排除某个自动配置类:

@EnableAutoConfiguration(exclude={SpringShellAutoConfiguration.class})

这样可以将jar包中的自动配置类排除并重写。

FAQ

  1. jar包中的一个接口实例化了一个bean,但是我们想实现自己的相同接口的其他bean(实现不同),这样默认jar包中锁注入的bean就会出现两个导致问题。
    解决:重写jar包中实例化bean的配置类,将该类设置为@Primary的,首选。

  2. 排除某个package中的配置类

在实际开发中,某些@Configration类可能额外的引入了我们不需要的功能,这个时候我们想要排除该类,而该类并非是自动配置类时:

@ComponentScan(basePackages = "com.microservice", excludeFilters = @ComponentScan.Filter(type =
		FilterType.ASSIGNABLE_TYPE, value = ResponseWrapConfiguration.class))
  1. 自动配置类实例,以redis的autoconfigration为例:
@Configuration
@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {
	@Configuration
	@ConditionalOnClass(GenericObjectPool.class)
	protected static class RedisConnectionConfiguration {

		private final RedisProperties properties;

		private final RedisSentinelConfiguration sentinelConfiguration;

		private final RedisClusterConfiguration clusterConfiguration;

		public RedisConnectionConfiguration(RedisProperties properties,
				ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
				ObjectProvider<RedisClusterConfiguration> clusterConfiguration) {
			this.properties = properties;
			this.sentinelConfiguration = sentinelConfiguration.getIfAvailable();
			this.clusterConfiguration = clusterConfiguration.getIfAvailable();
		}

		@Bean
		@ConditionalOnMissingBean(RedisConnectionFactory.class)
		public JedisConnectionFactory redisConnectionFactory()
				throws UnknownHostException {
			return applyProperties(createJedisConnectionFactory());
		}
}

你可能感兴趣的:(springboot,java)