SpringBoot中的Bean
1. spring的核心容器
Spring全家桶大家都很熟悉了,从原来的SpringMVC到现在的SpringBoot。核心容器包括了Beans、Core、Context、SpEL。
- core和beans模块提供了整个框架最基础的部分,包括了IOC和DI。
- Context建立在Core和Beans模块提供的基础之上:他提供了框架式访问对象的方式
- core、beans、context构成了Spring的骨架
- SpEL:提供了一种强大的用于在运行时操作对象的表达式语言
2.Spring与bean的关系
Spring容器是Spring的核心,一切SpringBean都存储在Spring容器内。可以说bean是spring核心中的核心。Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息来创建Bean实例,并调用Bean实例的方法来完成“依赖注入”,可以把Spring容器理解成一个大型工厂,Bean就是该工厂的产品,工厂(Spirng容器)里能生产出来什么样的产品(Bean),完全取决于配置文件中的配置。而这个配置是由开发人员创建和维护的,而在SpringBoot里面已经通过注解来实现,常用的bean注解有@Controller,@Service,@Component,还有@Configuration(bean的配置类)
3.使用@Componet配置bean
@Component
public class JdbcDemo {
private String name = "abc";
public String getName(){
return name;
}
}
这里很容易犯的一个错误就是包的路径问题,之前在junit的时候使用@Autowired无法扫描到bean,就是因为我的bean所在的路径不是在SpringBoot入口类Application同一个包或者是在它的子路径。一般运行会出现该异常提示
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
4.使用@Bean和@Configuration
@Configuration
public class JdbcConfiguration {
@Bean(name = "jdbcDemo2")
public JdbcDemo2 jdbcDemo2Bean(){
return new JdbcDemo2();
}
}
public class JdbcDemo2 {
private String name;
}
使用这种方法配置Bean的好处就是可以不限定bean的路径,但是已经用@Bean配置过得类不能再用其他bean的注解不然会造成冲突,但是使用lombok注解就没问题
使用场景:
在配置一些第三方的数据连接池对象时只能使用这种法术,例如阿里的druid项目。
@Configuration
public class DruidDBConfig {
private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.driverClassName}")
private String driverClassName;
@Value("${spring.datasource.initialSize}")
private int initialSize;
@Value("${spring.datasource.minIdle}")
private int minIdle;
@Value("${spring.datasource.maxActive}")
private int maxActive;
@Value("${spring.datasource.maxWait}")
private int maxWait;
@Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis;
@Value("${spring.datasource.minEvictableIdleTimeMillis}")
private int minEvictableIdleTimeMillis;
@Value("${spring.datasource.validationQuery}")
private String validationQuery;
@Value("${spring.datasource.testWhileIdle}")
private boolean testWhileIdle;
@Value("${spring.datasource.testOnBorrow}")
private boolean testOnBorrow;
@Value("${spring.datasource.testOnReturn}")
private boolean testOnReturn;
@Value("${spring.datasource.poolPreparedStatements}")
private boolean poolPreparedStatements;
@Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
private int maxPoolPreparedStatementPerConnectionSize;
@Value("${spring.datasource.filters}")
private String filters;
@Value("{spring.datasource.connectionProperties}")
private String connectionProperties;
@Bean //声明其为Bean实例
@Primary //在同样的DataSource中,首先使用被标注的DataSource
public DataSource dataSource(){
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(this.dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
//configuration
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
datasource.setPoolPreparedStatements(poolPreparedStatements);
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
try {
datasource.setFilters(filters);
} catch (SQLException e) {
logger.error("druid configuration initialization filter", e);
}
datasource.setConnectionProperties(connectionProperties);
return datasource;
}
}
其中@Value的注解是引用配置文件properties里面的参数,@Primary表示在同一的Datasource中,优先被使用
5.@Autowired注解的使用
@RunWith(SpringRunner.class)
@SpringBootTest
public class CommonTest {
@Autowired
DataSource dataSource;
@Autowired
JdbcDemo jdbcDemo;
@Autowired
JdbcDemo2 jdbcDemo2;
}
最后就是使用Autowired注解就可以直接获得Bean的对象,这就是Spring框架IOC的作用。
只要前进的方向正确,就算走得再慢,那也是在进步。