Spring注解总结

# 注册bean
@Component:bean的名字默认是类名首字母小写
@Repository:数据层
@Service:业务层
@Controller:控制器
# All component types are treated in the same way
# The subtypes are mere markers,think code readability rather than features
# There is no difference among the individual component types
# 属性注入
@Value:(字段,方法,参数,注解上)注入普通类型数据(使用的反射,不用提供set方法)
@Autowired:(构造器,字段,方法,参数,注解上)根据类型注入bean,不需要set方法
@Qualifier:结合@Autowired,根据名字注入
@Resource:根据类型或名字注入
# 指定了name,则只会按照name进行查找
# 没有指定name,先根据属性名查找,后根据类型查找

# @Autowired默认根据类型注入
# 同类型的bean只有一个,就将该bean装配给@Autowired指定的数据,此时变量名可以随便取
# 同类型的bean有多个,则根据变量名和bean的名字进行匹配,此时对变量名有要求
# 此时,可以通过修改变量名来指定使用哪一个,不想改变量名,也可以使用@Qualifier来指定注入bean的名称
// 示例
@Autowired
@Qualifier("stringRedisTemplate")
RedisTemplate req;
@Component
public class UserServiceImpl implements UserService,ApplicationContextAware {
    /**
     * Spring容器创建后,即已完成bean的创建
     * 会顺序执行 constructor -> 依赖注入 -> aware接口方法
     */
    public UserServiceImpl(){System.out.println("constructor...");}
    /**
     * 被 @Autowired和 @Value标注的方法,会在依赖注入时自动执行
     */
    @Value("sfsfg")
    public void test0(String kl){System.out.println(kl);}
    @Autowired
    public void test(BookService bookService){System.out.println(bookService);}
    @Autowired
    public void test2(List<BookService> list) {System.out.println(list);}

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println(applicationContext);
    }
}
@Bean:用在方法上,默认方法名作为bean名称,方法返回值作为bean对象
@Bean所在的类必须要被@Component标注
@Bean标注的方法的参数需要进行注入:
注入bean,可以不用管,@Autowired可以省略
注入指定bean,在参数前使用@Qualifier
注入普通类型,在参数前使用@Value
@Component
public class UserServiceImpl implements UserService {
    // bookService会进行自动注入,不用加@Autowired
    @Bean
    public DataSource dataSource(@Value("sdsd")String kl,BookService bookService){
        System.out.println(kl);
        System.out.println(bookService);
        return new DruidDataSource();
    }
}
@Configuration:标注当前类是一个配置类(替代xml配置文件),并且当前类也会被注册为bean
单例池中的是配置类的代理对象,使用的是CGLIB代理
springConfig -> {SpringConfig$$EnhancerBySpringCGLIB$$bcafab34@2100}
@ComponentScan:扫描指定包下的bean,不指定则扫描配置类所在包及其子包
@PropertySource:加载资源文件
@Import:
1.引入普通类(会将普通类注入Spring容器,beanName是普通类的全限定名)
2.引入@Configuration标注的类(注入到单例池中的是该类的cglib代理对象)

@Import可以添加在@SpringBootApplication(启动类)、@Configuration(配置类)、@Component(组件类)对应的类上
如果配置类在标准的SpringBoot包结构下(SpringBootApplication启动类包的根目录下)。是不需要@Import导入配置类的,SpringBoot自动帮做了。
@Configuration中所有带@Bean注解的方法都会被动态代理,只会被执行一次。
被@Configuration修饰的类,spring容器中会通过cglib给这个类创建一个代理,代理会拦截所有被@Bean修饰的方法。
默认情况(bean为单例)下确保这些方法只被调用一次,从而确保这些bean是同一个bean,即单例的。
如果不加@Configuration,则不保证被@Bean注解的方法只被执行一次,即若存在Bean之间的依赖,则方法会被执行多次,生成几个不同的Bean对象。

Full Mode

Typically, @Bean methods are declared within @Configuration classes. In this case, bean methods may reference other @Bean methods in the same class by calling them directly. This ensures that references between beans are strongly typed and navigable. Such so-called ‘inter-bean references’ are guaranteed to respect scoping and AOP semantics, just like getBean() lookups would. These are the semantics known from the original ‘Spring JavaConfig’ project which require CGLIB subclassing of each such configuration class at runtime. As a consequence, @Configuration classes and their factory methods must not be marked as final or private in this mode.

Lite Mode

官方定义为:在没有标注@Configuration的类里面有@Bean方法就称为Lite模式的配置。透过源码再看这个定义是不完全正确的,而应该是有如下case均认为是Lite模式的配置类:
类上标注有@Component注解
类上标注有@ComponentScan注解
类上标注有@Import注解
类上标注有@ImportResource注解
类上没有任何注解,但类中存在@Bean方法
以上case的前提均是类上没有被标注@Configuration,在Spring 5.2之后新增了一种case也算作Lite模式:
标注有@Configuration(proxyBeanMethods = false),注意:此值默认是true哦,需要显示改为false才算是Lite模式
自Spring5.2(对应Spring Boot 2.2.0)开始,内置的几乎所有的@Configuration配置类都被修改为了@Configuration(proxyBeanMethods = false),以此来降低启动时间,为Cloud Native继续做准备。
@Bean methods may also be declared within classes that are not annotated with @Configuration. For example, bean methods may be declared in a @Component class or even in a plain old class. In such cases, a @Bean method will get processed in a so-called ‘lite’ mode.

Bean methods in lite mode will be treated as plain factory methods by the container (similar to factory-method declarations in XML), with scoping and lifecycle callbacks properly applied. The containing class remains unmodified in this case, and there are no unusual constraints for the containing class or the factory methods.

In contrast to the semantics for bean methods in @Configuration classes, ‘inter-bean references’ are not supported in lite mode. Instead, when one @Bean-method invokes another @Bean-method in lite mode, the invocation is a standard Java method invocation; Spring does not intercept the invocation via a CGLIB proxy.
当@Bean方法在没有使用@Configuration注释的类中声明时,它们被称为在Lite模式下处理。它包括:在@Component中声明的@Bean方法,甚至只是在一个非常普通的类中声明的Bean方法,都被认为是Lite版的配置类。@Bean方法是一种通用的工厂方法(factory-method)机制。
和Full模式的@Configuration不同,Lite模式的@Bean方法不能声明Bean之间的依赖关系。因此,这样的@Bean方法不应该调用其他@Bean方法。每个这样的方法实际上只是一个特定Bean引用的工厂方法(factory-method),没有任何特殊的运行时语义。
@Configuration和@Bean注解详解
@EnableConfigurationProperties

@EnableConfigurationProperties({SpringBootShardingRuleConfigurationProperties.class, 
SpringBootMasterSlaveRuleConfigurationProperties.class})
// {}中的类都标注的有 @ConfigurationProperties,但是没标注 @Component,
// @EnableConfigurationProperties将这些类都注入到 IOC 容器中

@ConditionalOnProperty

@ConditionalOnProperty(
    prefix = "spring.shardingsphere",
    name = {"enabled"},				// 配置文件中 spring.shardingsphere.enabled 属性值不为false时, 加载这个Bean
    havingValue = "true",			// 和 name 搭配使用, name中的属性值和havingValue的值一样时, 加载这个Bean
    matchIfMissing = true			// 当name中的属性在配置文件中没有的时候, 也会加载这个Bean
)

@Conditional

    @Bean
    // 是否加载要根据 matches 方法的返回值
    // 如果有多个Conditon,则需要所有Condition返回true才能对当前类进行注册配置
    @Conditional({MasterSlaveRuleCondition.class})
    public DataSource masterSlaveDataSource(){
		...
    }
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
	// 需要实现了Condition接口的Class实例对象
    Class<? extends Condition>[] value();
}
@FunctionalInterface
public interface Condition {
	// 方法的返回值决定是否对当前类进行注册配置
    boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}

@ConditionalOnClass
@ConditionalOnClass({RedisOperations.class})
当指定的类存在于classpath中时,才会构建Bean
@ConditionalOnBean
当给定的bean存在时,则实例化当前Bean
@ConditionalOnMissingBean
当给定的bean不存在时,则实例化当前Bean
@AutoConfigureAfter
@AutoConfigureAfter({RedisAutoConfiguration.class})
在 RedisAutoConfiguration之后加载
@ConditionalOnProperty注解
@Conditional
@Conditional注解
@Configuration
@Resource和@Autowired有啥区别

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值