装配Bean:
1.自动扫描:
@ComponentScan+@Component
@ComponentScan标明采用何种策略去扫描装配Bean
@Component标明哪个类被扫描进入IOC容器
2.自定义第三方Bean:
@Bean+@Configuration/@Component
initMethod() destroyMethod()
FULL模式和LITE模式
FULL:标注有@Configuration注解的类被称为full模式的配置类。
LITE:当@Bean方法在没有使用@Configuration注释的类中声明时,他们被称为在Lite模式下处理。
FULL模式下,配置类会被CGLIB增强(生成代理对象),放进IOC容器内的是代理;该模式下,配置类内部可以通过方法调用来处理依赖,并且能够保证是同一个实例,都指向IOC内的那个单例。
该模式下@bean方法不能被private/final修饰。
LITE模式下,配置类不会被增强,放进IOC容器内的就是本尊,配置类内部不能通过方法调用来处理依赖,否则内次都生成的事一个新的实例而并非IOC容器内的单例。
该模式下配置类就是一普通类,所以@Bean方法可以使用private/final进行修饰。
FULL模式: @Configuration public class ClassA { @Bean public String A(){ System.out.println("createA"); return ""; } @Bean public String B(){ A(); System.out.println("createB"); return ""; } }
结果:createA createB
LITE模式: @Component public class ClassA { @Bean public String A(){ System.out.println("createA"); return ""; } @Bean public String B(){ A(); System.out.println("createB"); return ""; } }
结果:createA createA createB
Bean作用域
作用域 | 描述 |
singleton | 默认值,IOC容器只存在单例 |
prototype | 每当从IOC容器中取出一个Bean,则创建一个新的Bean |
request | 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于web的Spring WebApplicationContext环境 |
session | 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境 |
application | 限定一个Bean的作用域为ServletContext的生命周期。该作用域仅适用于web的Spring WebApplicationContext环境。 |
Bean注入消除歧义:
当一个借口有2个不同的实现时,使用@Autowired会报错,此时使用@Primary注解,此注解表示这个bean优先于其他bean。
或者用@Qualifier指定注入Bean的名称
注入配置文件的值
@Value
@ConfigurationProperties
@PropertySource加载指定的配置文件,如@PropertySource("classpath:jdbc.properties")
区别:
区别 | @Configuration | @Value |
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定 | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
Spring EL
${...}代表占位符
#{...}启用spring表达式,具有运算功能
/* * @Value注解等同于XML配置中的<property/>标签, * SpringEL同样支持在XML<property/>中编写 */ // 注入简单值,输出num为5 @Value("#{5}") private Integer num; // 注入ID为testConstant的Bean @Value("#{testConstant}") private TestConstant Constant; // 注入ID为testConstant Bean中的STR常量/变量 @Value("#{testConstant.STR}") private String str;
SpEL调用方法:
/* * TestConstant类中有两个方法重载, * 返回值为String类型 */ // 调用无参方法 @Value("#{testConstant.showProperty}") private String method1; // 有参接收字符串的方法 @Value("#{testConstant.showProperty('Hello')}") private String method2; /* * 若然希望方法返回的String为大写 */ @Value("#{testConstant.showProperty().toUpperCase()}") private String method3; /* * 若使用method3这种方式,若然showProperty返回为null, * 将会抛出NullPointerException,可以使用以下方式避免 */ @Value("#{testConstant.showProperty()?.toUpperCase}") private String method4;
SpringEL进行运算及逻辑操作:
// 拼接字符串 @Value("#{testConstant.nickname + ' ' + testConstant.name}") private String concatString; // 对数字类型进行运算,testConstant拥有num属性 @Value("#{ 3 * T(java.lang.Math).PI + testConstant.num}") private double operation; // 进行逻辑运算 @Value("#{testConstant.num > 100 and testConstant.num <= 200}") private boolean logicOperation; // 进行或非逻辑操作 @Value("#{ not testConstant.num == 100 or testConstant.num <= 200}") private boolean logicOperation2; // 使用三元运算符 @Value("#{testConstant.num > 100 ? testConstant.num : testConstant.num + 100}") private Integer logicOperation3; }
Web相关注解
一个请求方法只可以有一个@RequestBody,但是可以有多个@RequestParam和@PathVariable
@RequestParam - 获取查询参数
@PathVariable - 获取路径参数
如下:
请求:/test/1/ss?name=abc
即 id=1 name=abc
@GetMapping("/test/{id}/ss") public String ss(@PathVariable("id") Long id, @RequestParam(value = "name", required = false) String name){ System.out.println("ss"); return "ss"; }