1.Conditional相关注解
spring.factories文件里每一个xxxAutoConfiguration文件一般都会有下面的条件注解:
@ConditionalOnBean:当容器里有指定Bean的条件下
@ConditionalOnClass:当类路径下有指定类的条件下
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JV版本作为判断条件
@ConditionalOnJndi:在JNDI存在的条件下差在指定的位置
@ConditionalOnMissingBean:当容器里没有指定Bean的情况下
@ConditionalOnMissingClass:当类路径下没有指定类的条件下
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径是否有指定的值
@ConditionalOnSingleCandidate:当指定Bean在容器中只有一个,或者虽然有多个但是指定首选Bean
@ConditionalOnWebApplication:当前项目是Web项目的条件下。
上面@ConditionalOnXXX都是组合@Conditional元注解,使用了不同的条件Condition
@Conditional注解使用如下:
package com.wangcongming.cache.condition;
import com.wangcongming.cache.util.PropertyClientUtill;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
import java.io.File;
/**
* @Auther: wangcongming
* @Date: 2018/7/16 15:07
* @Description:
*/
public class DoubleCacheCondition implements Condition {
/**
*
* @param context 判断条件能使用的上下文(环境)
* @param annotatedTypeMetadata 注解信息
* @return
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata annotatedTypeMetadata) {
//1、能获取到ioc使用的beanfactory
// ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// //2、获取类加载器
// ClassLoader classLoader = context.getClassLoader();
// //3、获取当前环境信息
// Environment environment = context.getEnvironment();
// //4、获取到bean定义的注册类
// BeanDefinitionRegistry registry = context.getRegistry();
String rootPath = PropertyClientUtill.class.getClassLoader().getResource("").getPath();
String path = String.format("%s%s",rootPath,"double-cache.properties");
File file = new File(path);
//判断是否存在 double-cache.properties
return file.exists();
}
}
@Conditional(DoubleCacheCondition.class)
@Bean
@Primary
public CacheManager cacheManager() {
LayeringCacheManager layeringCacheManager = new LayeringCacheManager(redisTemplate);
// 设置默认的一级缓存配置
String specification = this.cacheProperties.getCaffeine().getSpec();
if (StringUtils.hasText(specification)) {
layeringCacheManager.setCaffeineSpec(CaffeineSpec.parse(specification));
}
layeringCacheManager.setAllowNullValues(false);
return layeringCacheManager;
}
直接使用@Conditional注解,需要自己实现一个org.springframework.context.annotation.Condition的实现类,condition接口只有一个方法,这个方法有两个参数ConditionContext context, AnnotatedTypeMetadata annotatedTypeMetadata,他返回结果为true代表加载被注解的bean,返回false代表不加载。
2.@PostConstruct和@PreDestroy
@postconstruct初始化的操作
从Java EE 5规范开始,Servlet中增加了两个影响Servlet生命周期的注解(Annotion);
@PostConstruct和@PreDestroy。这两个注解被用来修饰一个非静态的void()方法 。
写法有如下两种方式:
@PostConstruct
Public void someMethod() {}
或者
public @PostConstruct void someMethod(){}
被@PostConstruct修饰的方法会在服务器加载Servle的时候运行,并且只会被服务器执行一次。
PostConstruct在构造函数之后执行,init()方法之前执行。
PreDestroy()方法在destroy()方法执行执行之后执行
具体使用如下:
package com.wangcongming.springlearn.springlearn.util;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @Auther: wangcongming
* @Date: 2018/7/17 13:45
* @Description:
*/
@Component
public class PropertiesUtils {
Properties properties = new Properties();
@PostConstruct
public void init(){
try {
InputStream inputStream = PropertiesUtils.class.
getClassLoader().getResourceAsStream("abc.properties");
properties.load(inputStream);
} catch (IOException e) {
}
}
public String getProperties(String key){
return properties.getProperty(key);
}
}
@Autowired
private PropertiesUtils propertiesUtils;
@GetMapping("test")
public String test(){
String name = propertiesUtils.getProperties("name");
System.out.println(name);
String age = propertiesUtils.getProperties("age");
System.out.println(age);
String sex = propertiesUtils.getProperties("sex");
System.out.println(sex);
return name;
}
运行结果如下:
3.@ComponentScan注解
@ComponentScan注解是用来指定compoment扫描包的路径的
@ComponentScan value:指定要扫描的包
excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
FilterType.ANNOTATION:按照注解
FilterType.ASSIGNABLE_TYPE:按照给定的类型; 只需要直接指定类型即可
FilterType.ASPECTJ:使用ASPECTJ表达式
FilterType.REGEX:使用正则指定
FilterType.CUSTOM:使用自定义规则
- FilterType.ANNOTATION:按照注解
示例如下:
注解定义
package com.wangcongming.annotation;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ExcludeFilter {
}
使用直接标注类
package com.wangcongming.shop.score.config;
import com.wangcongming.annotation.ExcludeFilter;
import feign.Contract;
import feign.Feign;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
@ExcludeFilter
public class FeignOneConfiguration {
@Bean
public Contract feignContract(){
return new feign.Contract.Default();
}
/**
* 查看org.springframework.cloud.netflix.feign.FeignClientsConfiguration可以发现
* @Bean
* @Scope("prototype")
* @ConditionalOnMissingBean
* @ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = false)
* public Feign.Builder feignHystrixBuilder() {
* return HystrixFeign.builder();
* }
* 可以看出当feign.hystrix.enabled配置为true时,默认开启HystrixFeign.builder()
* @return
*/
@Bean
@Scope("prototype")
public Feign.Builder feignBuilder() {
return Feign.builder();
}
}
在入口类上使用注解@ComponentScan
- FilterType.CUSTOM:使用自定义规则
入口类添加注解如下:
@ComponentScans(
value = {
@ComponentScan(value="com.atguigu",excludeFilters = {
@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})
})
}
)
编写过滤规则
package com.atguigu.config;
import java.io.IOException;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
public class MyTypeFilter implements TypeFilter {
/**
* metadataReader:读取到的当前正在扫描的类的信息
* metadataReaderFactory:可以获取到其他任何类信息的
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
// TODO Auto-generated method stub
//获取当前类注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前类资源(类的路径)
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
System.out.println("--->"+className);
if(className.contains("er")){
return true;
}
return false;
}
}
4.自动注入依赖注解
目前来说有以下注解可以使用
- @Autowired
@Autowired是spring提供的注解
1)默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值
2)、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找applicationContext.getBean("bookDao")
3)、@Qualifier("bookDao"):使用@Qualifier指定需要装配的组件的id,而不是使用属性名
4)、自动装配默认一定要将属性赋值好,没有就会报错;当然也可以使用@Autowired(required=false)指定,这样没有找到就不会报错了
5)、@Primary:让Spring进行自动装配的时候,默认使用首选的bean;也可以继续使用@Qualifier指定需要装配的bean的名字
- Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[java规范的注解]
1.@Resource(JSR250)
1)可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;
2)没有能支持@Primary功能没有支持@Autowired(reqiured=false);
2.@Inject(JSR330)
1)需要导入javax.inject的包,和Autowired的功能一样。
2)没有required=false的功能;
注:导入依赖如下:
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
5. @JsonView
@JsonView是jackson json中的一个注解,Spring webmvc也支持这个注解,它的作用就是控制输入输出后的json
分享一套spring boot 学习视频:https://download.csdn.net/download/linhui258/10546450