spring boot 之部分注解详解

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:按照注解

示例如下:

注解定义

扫描二维码关注公众号,回复: 3235616 查看本文章
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

猜你喜欢

转载自blog.csdn.net/linhui258/article/details/81080198