@ConfigurationProperties ; @Component ; @Value ; @Validated
/**
* @ConfigurationProperties:
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;此注解注入属性的时候一定要提供set方法
* prefix = "person":配置文件中person下面的所有属性进行一一映射
* @Component:
将组件注入到容器中,只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能;
@Value:
用@value注入属性的时候就不用@ConfigurationProperties注解了
* @Validated:
开启数据校验,只有@ConfigurationProperties批量注入属性的时候才能生效@value不生效
*/
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
@Email
// @Value("${person.lastName}") //不支持数据校验 不是电子邮件格式也可以
private String lastName;
private Integer age;
private boolean boss;
private Date birth;
// @Value("${person.lists}") 可以注入list
private List<Object> lists;
// @Value("${person.maps}") 无法注入map
private Map<String, Object> maps;
private Dog dog;
}
@Value获取值和@ConfigurationProperties获取值比较
@ConfigurationProperties | @Value(无需提供get/set方法也可以注入) | |
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 (last-name 对 lastname lastName都能绑定) | 不支持 |
SpEL | 不支持 | 支持 #{10*2} |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 ${person.maps}无法获取到多个键值对 |
如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;
@PropertySource ;@ImportResource
/**
*@PropertySource:加载指定的配置文件 person的属性值没有配置在默认的配置文件里,而是在persion.properties里
*/
@PropertySource(value = {"classpath:person.properties","classpath:dog.properties"})
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
@Email
// @Value("${person.lastName}") //不支持数据校验 不是电子邮件格式也可以
private String lastName;
private Integer age;
private boolean boss;
private Date birth;
// @Value("${person.lists}") 可以注入list
private List<Object> lists;
// @Value("${person.maps}") 无法注入map
private Map<String, Object> maps;
private Dog dog
}
@ImportResource 作用:
/**
@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效;
Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;
想让Spring的配置文件生效,加载进来;@ImportResource标注在一个配置类上
*/
①需要spring配置文件注入IOC容器的类(此处不用注解注入)
public class HelloWorldService {
}
②spring的xml配置文件加载此bean到IOC容器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id = "helloWorldService" class="com.example.service.HelloWorldService"></bean>
</beans>
③配置类上加上@ImportResource注解 引入Spring的配置文件
@ImportResource(locations = {"classpath:beans.xml"})
@SpringBootApplication
public class SpringBootQuickApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootQuickApplication.class, args);
System.out.println("Spring Boot started... ...");
}
}
④测试类测试是否获取bean
@RunWith(SpringRunner.class) //用Spring的单元测试驱动器来跑 而不是用Junit
@SpringBootTest
public class SpringBootQuickApplicationTests {
@Autowired
HelloWorldService helloWorldService;
@Test
public void testSpringXML() {
System.out.println(helloWorldService);
System.out.println("####################################################################");
}
}
@Configuration ;@Bean ; @Scope ; @Lazy ; @Conditional ;@Import
/**
@Configuration:
SpringBoot推荐给容器中添加组件的方式;推荐使用全注解的方式,而不是@ImportResource配置文件,
即:配置类@Configuration替代之前的Spring.xml配置文件
@Bean代表了 XML配置文件中的bean标签:
<bean id = "helloWorldService" class="com.example.service.HelloWorldService"></bean>
@SpringBootConfiguration:
Spring Boot的配置类;标注在某个类上,表示这是一个Spring Boot的配置类;
@Configuration:配置类上来标注这个注解;
配置类 ----- 配置文件;
配置类也是容器中的一个组件所以里面有@Component注解注释
@EnableAutoConfiguration:
开启自动配置功能;
以前我们需要配置的东西,Spring Boot帮我们自动配置;
@EnableAutoConfiguration告诉SpringBoot开启自动配置功能;这样自动配置才能生效;
*/
声明一个配置类
package com.example.config;
import com.example.service.HelloWorldManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Created by wangxiaodong on 2018/6/
* @Configuration:指明当前类是一个配置类;就是来替代之前的Spring配置文件
* 在配置文件中我们是用<bean><bean/>标签添加组件 注解的方式就是@Bean
*/
@Configuration
@Import({FdfsClientConfig.class,Color.class})//快速导入bean bean的id默认是全类名
public class MyAppConfig {
//将方法的返回值添加到容器中;容器中这个组件默认的bean的id就是方法名:helloWorldManager 如果@bean(value="newBeanIdName")bean的id就会变成newBeanIdName
@Bean(initMethod = "init",destroyMethod = "destroy")
//singleton 单例:IOC容器创建的时候创建此对象; @Lazy懒加载:使用的时候才创建对象 ;IOC容器关闭调用销毁方法
//prototype 多例:IOC容器创建的时候不创建此对象,使用的时候创建,并且每回都重新创建;IOC容器关闭的时候不会调用销毁方法
@Scope("singleton")
@Lazy
@Conditional(OnBeanCondition.class) //满足某种条件才能创建对象 OnBeanCondition.class自定义的类进行条件匹配
public HelloWorldManager helloWorldManager(){
return new HelloWorldManager();
}
}
@ComponentScan ;@Filter ;@ComponentScans(value = {ComponentScan 数组})
@SpringBootApplication
//@EnableRedisHttpSession
@ComponentScan(value = "com.taxpay",
excludeFilters = {//排除扫描的包 excludeFilters是数组
@ComponentScan.Filter(type = FilterType.ANNOTATION,//扫描排除以下注解的
classes = {Controller.class, Service.class}) //classes是数组
})
@ComponentScan(value = "com.taxpay",
includeFilters = {//扫描只包含的包 includeFilters是数组
@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes = {Controller.class})//classes是数组
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, //扫描以下类型的
classes = {ServiceDelegate.class})
},
useDefaultFilters = false) //useDefaultFilters=false 禁用掉默认过滤规则 只包含(includeFilters)才能生效)
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class WebApplication extends SpringBootServletInitializer {
@Profile
/**
* Profile:
* Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;
*
* 开发环境、测试环境、生产环境;
* 数据源:(/A)(/B)(/C);
*
*
* @Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件
*
* 1)、加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境
* 2)、写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
* 3)、没有标注环境标识的bean在,任何环境下都是加载的;
*/
@PropertySource("classpath:/dbconfig.properties")
@Configuration
public class MainConfigOfProfile implements EmbeddedValueResolverAware{
@Value("${db.user}")
private String user;
private StringValueResolver valueResolver;
private String driverClass;
@Bean
public Yellow yellow(){
return new Yellow();
}
@Profile("test")
@Bean("testDataSource")
public DataSource dataSourceTest(@Value("${db.password}")String pwd) throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Profile("dev")
@Bean("devDataSource")
public DataSource dataSourceDev(@Value("${db.password}")String pwd) throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm_crud");
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Profile("prod")
@Bean("prodDataSource")
public DataSource dataSourceProd(@Value("${db.password}")String pwd) throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/scw_0515");
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
// TODO Auto-generated method stub
this.valueResolver = resolver;
driverClass = valueResolver.resolveStringValue("${db.driverClass}");
}
}
@EnableAspectJAutoProxy ; @Aspect
开启AOP三步:
* 1)、将业务逻辑组件和切面类都加入到容器中;告诉Spring哪个是切面类(@Aspect)
* 2)、在切面类上的每一个通知方法上标注通知注解,告诉Spring何时何地运行(切入点表达式)
* 3)、开启基于注解的aop模式;给配置类中加 @EnableAspectJAutoProxy
@EnableTransactionManagement ;@Transactional
声明式事务:
* 1、导入相关依赖
* 数据源、数据库驱动、Spring-jdbc模块
* 2、配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据
* 3、给方法上标注 @Transactional 表示当前方法是一个事务方法;
* 4、 @EnableTransactionManagement 配置类中加入此注解开启基于注解的事务管理功能;
* 5、配置事务管理器来控制事务;
* @Bean
* public PlatformTransactionManager transactionManager()
@EnableTransactionManagement
@ComponentScan("com.atguigu.tx")
@Configuration
public class TxConfig {
//数据源
@Bean
public DataSource dataSource() throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("123456");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
return dataSource;
}
//
@Bean
public JdbcTemplate jdbcTemplate() throws Exception{
//Spring对@Configuration类会特殊处理;给容器中加组件的方法,多次调用都只是从容器中找组件
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
return jdbcTemplate;
}
//注册事务管理器在容器中
@Bean
public PlatformTransactionManager transactionManager() throws Exception{
return new DataSourceTransactionManager(dataSource());
}
}
SpringBoot注册组件(bean)的方法
1)包扫描@ComponentScan + 组件标注注解(@Controller/@Service...... 但是只能注册自己写的组件)
2)@Bean :导入第三方包里的组件
3)@Import:快速在容器中导入一个组件
a) @Import({FdfsClientConfig.class,Color.class})//快速导入bean bean的id默认是全类名
b) @Import({FdfsClientConfig.class,Color.class,MyImportSelector.class })
ImportSelector : 实现此接口返回需要导入的全类名
c) @Import({FdfsClientConfig.class,Color.class,MyImportBeanDefinitionRegistrar.class })
ImportBeanDefinitionRegistrar:实现此接口,手动注册bean到容器中
4)使用spring提供的FactoryBean (工厂bean)