13、SpringBoot之配置类@Configuration
01、概述
配置类:在springboot中被@Configuration或者@SpringBootConfiguration标注的类称之为配置类。
02、作⽤&⽬的
在配置类可以定义很多@Bean的⽅法,可以让这些@Bean修饰的⽅式让spring框架加载到ioc容器中去。
03、那为什么会存在配置
⽅便你覆盖底层的配置类
让你去扩展的bean的⼀种机制。
04、⼀个springboot项⽬中的加载的bean有那些呢?
程序员⾃⼰编写的开发的bean ,⽐如加了:
@Service,@Mapper,@Controller,@RestController,@Component,@Repository的类,都会加载到ioc容器中。
如果⼀个类加了注解就能够加载到ioc容器中去吗?
不能,需要@ComponentScan扫包才⾏。刚好springboot的注解是⼀个复合注解其中就包含了@ComponentScan注解,然后springbooot启动类启动会去扫包把这些加了注解的bean全部加ioc容器中
Starter提供配置配置类+@Bean也会加载到ioc容器中。
05、思考为什么会存在配置类?
它其实就⼀种额外扩展和加载bean的⼀种机制。
可以⽅便进⾏额外的扩展和引⽤第三⽅的bean。如果没有这种机制,那么所以的中间件⽐如:mybatis,redis,jpa,kafka等这些初始化并且放⼊到ioc容器中必须全部要⾃⼰取编写。
springboot为了解放程序开发⼈员,所以提供starter机制,⽽这些个starter机制⾥⾯的原理全部都是:配置类+@Bean
如果官⽅提供的满⾜不了,当然你可以⾃⼰取定义配置类和@Bean⽅法进⾏加载到ioc容器中,进⾏额外扩展。
06、定义⼀个配置类
1:准备⼀个接⼝:
package;
public interface IUserService {
public void sayHello();
}
2:准备⼀个实现类
package;
import Service;
public class UserServiceImpl implements IUserService {
@Override
public void sayHello(){
System.out.println("nihao");
}
}
3:给bean定义配置将其初始化
package;
import IUserService;
import UserServiceImpl;
import Bean;
import Configuration;
@Configuration
public class UserConfiguration {
@Bean
public IUserService getUserService(){
return new UserServiceImpl();
}
}
注意事项1:@Bean必须定义在配置类中@Configuration或者加了spring注解
(@Service,@Mapper,@Controller,@RestController,@Component,@Repository),如果没有@Bean不会有效。
注意事项2:如果是扫包的情况下(@Mapper@Service等):默认是以类名⼩写作为key进⾏映射。如果是@Bean,以⽅法名(以下是xxxxxxxxxxxx)作为key进⾏容器映射。如果你在@Bean(“oxksxjxj
xxhxjxhxhj”) 那么就⽤你指定的名字进⾏映射。
注意事项3:虽然@Bean可以结合spring的其他注解也可以加载到ioc容器中,但是还是推荐使⽤@Configuration,这样更加明确。因为它们黄⾦搭档。
05、条件注解
默认情况,假设没有条件注解,那么发⽣什么?因为如果bean指定@Configuration和@Bean是必须⼀定加载ioc容器中去的.
思考⼀个问题:springboot的starter机制中提供了100~200个配置类,这么的多配置类,我们不可能全不让ioc容器加载,因为项⽬可能之⽤到了redis,mybatis ,那么另外100多个,应该不要加载才⾏。所以条件注解就专门来做过滤使⽤。满⾜配置就加载,不满⾜的就忽略。
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* /licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package;
import EnableAutoConfiguration;
import ConditionalOnClass;
import ConditionalOnMissingBean;
import ConditionalOnSingleCandidate;
import EnableConfigurationProperties;
import Bean;
import Configuration;
import Import;
import RedisConnectionFactory;
import RedisOperations;
import RedisTemplate;
import StringRedisTemplate;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Redis support.
*
* @author Dave Syer
* @author Andy Wilkinson
* @author Christian Dupuis
* @author Christoph Strobl
* @author Phillip Webb
* @author Eddú Meléndez
* @author Stephane Nicoll
* @author Marco Aust
* @author Mark Paluch
* @since 1.0.0
*/
@Configuration(proxyBeanMethods =false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name ="redisTemplate")
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object>redisTemplate(RedisConnectionFactory redisConnectionFactory){ RedisTemplate<Object, Object> template =new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){ return new StringRedisTemplate(redisConnectionFactory);
springboot框架的作用}
}
07、相同类型的怎么办?
package;
import IUserService;
import UserServiceImpl;
import Qualifier;
import ConditionalOnBean; import ConditionalOnClass; import ConditionalOnMissingBean; import Bean;
import Configuration;
import Primary;
import Component;
import Controller;
import Service;
@Configuration
public class UserConfiguration {
@Bean
public IUserService getUserService1(){
System.out.println("2222222222222222222222222222222");
return new UserServiceImpl();
}
@Bean
public IUserService getUserService2(){
System.out.println("11111111111111111111111111");
return new UserServiceImpl();
}
}
上⾯的代码:出现⼀个接⼝有两个⼦类,如果初始化就会报错:
解决⽅案1:使⽤@Qualifier
@Autowired
@Qualifier("getUserService1")
private IUserService userService;
解决⽅案2:名字匹配
@Autowired
private IUserService getUserService1;
@Autowired
private IUserService getUserService2;
解决⽅案3:@Primary
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论