@Configuration
表示该类为配置类,相当于Spring的xml配置文件,然后会在该类中注入一些bean对象,项目中一般注入的是第三方的依赖对象,通常会结合@ComponentScan注解一起使用,扫包范围的包
package com.mayikt.v2.config;
import com.mayikt.v1.entity.UserEntity;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @Description: 配置
* @Author: ChenYi
* @Date: 2020/07/02 20:43
**/
@Configuration
@ComponentScan("com.mayikt.v2")
public class MySpringConfig {
@Bean
public UserEntity userEntity(){
return new UserEntity("20", "小林");
}
}
@ComponentScan
扫包范围的注解,通过引入这个注解会在容器加载的时候去对应的包下面扫需要往Spring容器中注入的对象
excludeFilters 指把在某个包下面的某个注解的对象给去掉,不放入Spring容器中
@ComponentScan(value = "com.mayikt.v2",
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class)},useDefaultFilters = true)
includeFilters 指把在某个包下面的加了某个注解的对象注入Spring容器中
@ComponentScan(value = "com.mayikt.v2",
includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class)},useDefaultFilters = false)
@Scope
标识注入的对象是单例还是多例的,默认是singleton单例的,spring容器注入对象的时候注解不加这个注解的时候默认创建的也是单例的,项目中一般需要指定是多例的才会用到这个注解
package com.mayikt.v2.controller;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
/**
* @Description:
* @Author: ChenYi
* @Date: 2020/07/02 20:52
**/
@Controller
@Scope("prototype")
public class UserController {
}
@Lazy
表示spring容器中的对象的创建时懒汉式还是饿汉式,如果不加这个注解的时候Spring容器中创建的对象默认是饿汉式的,也就是说在加载容器的时候就会创建对象,当使用这个注解的时候默认是true懒汉式的,当使用对象的时候才会去创建对象,false的时候表示该对象是饿汉式的,项目中一般需要懒加载对象的时候才会用到该注解
@Conditional
通过这个注解可以实现选择性的注入Bean操作
下面举例 在Spring容器加载中,如果当前环境是Win10就装配winEntity实体类
。
package com.mayikt.v3.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* @Description:
* @Author: ChenYi
* @Date: 2020/07/02 23:14
**/
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String name = environment.getProperty("os.name");
if ("Windows 10".equals(name)) {
return true;
}
return false;
}
}
package com.mayikt.v3.config;
import com.mayikt.v3.condition.MyCondition;
import com.mayikt.v3.entity.WinEntity;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
/**
* @Description: spring配置类
* @Author: ChenYi
* @Date: 2020/07/02 23:07
**/
@Configuration
public class MySpringConfig {
@Bean
@Conditional(MyCondition.class)
public WinEntity winEntity() {
return new WinEntity();
}
}
@Bean
往容器中注入对象,一般是注入第三方的对象,如果是系统内部的,直接用@component注解就可以了,默认beanId是方法名称
@Import
是被用来整合所有在@Configuration注解中定义的bean配置,默认注册beanid为 全路径地址
package com.mayikt.v3.config;
import com.mayikt.v3.entity.WinEntity;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* @Description: spring配置类
* @Author: ChenYi
* @Date: 2020/07/02 23:07
**/
@Configuration
@Import(WinEntity.class)
public class MySpringConfig {
}
@import和@Bean注解的区别
两个注解都是用来引入外部类,@Bean注解注册的bean的id是以方法名称命名, @Import以当前类完整路径地址注册,注入类更加简单
@EnableXXX
主要是用在SpringBoot项目中,封装了一层引入某个对象,开启某个功能的注解,底层是使用了@import注解把某个类注册进来的
下面展示一些 如@EnableDiscoveryClient服务发现注解,底层也是使用了@Import注解把某个类注册进spring容器中
。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({EnableDiscoveryClientImportSelector.class})
public @interface EnableDiscoveryClient {
boolean autoRegister() default true;
}
自定义一个@EnablePayEntity注解如下
package com.mayikt.v3.annotation;
import com.mayikt.v3.entity.PayEntity;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* @author caitou
* @date 2020/7/2 23:48
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(PayEntity.class)
public @interface EnablePayEntity {
}
package com.mayikt.v3.config;
import com.mayikt.v3.annotation.EnablePayEntity;
import org.springframework.context.annotation.Configuration;
/**
* @Description: spring配置类
* @Author: ChenYi
* @Date: 2020/07/02 23:07
**/
@Configuration
@EnablePayEntity
public class MySpringConfig {
}
ImportSelector
importSelector接口是至spring中导入外部配置的核心接口,在SpringBoot的自动化配置和@EnableXXX都有它的存在,可以批量的注册类
下面展示一些 自定义的ImportSelector导入类
。
实现ImportSelector的接口
package com.mayikt.v3.selector;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* @Description:
* @Author: ChenYi
* @Date: 2020/07/03 07:24
**/
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.mayikt.v3.entity.OrderEntity","com.mayikt.v3.entity.SmsEntity"};
}
}
自定义@EnableImportSelector 注解
package com.mayikt.v3.annotation;
import com.mayikt.v3.selector.MyImportSelector;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* @author caitou
* @date 2020/7/3 7:32
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyImportSelector.class)
public @interface EnableImportSelector {
}
使用@EnableImportSelector注解
package com.mayikt.v3.config;
import com.mayikt.v3.annotation.EnableImportSelector;
import org.springframework.context.annotation.Configuration;
/**
* @Description: spring配置类
* @Author: ChenYi
* @Date: 2020/07/02 23:07
**/
@Configuration
@EnableImportSelector
public class MySpringConfig {
}
ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar手动注册Bean
下面展示一些 自定义的例子
。
自定义的ImportBeanDefinitionRegistrar的类实现ImportBeanDefinitionRegistrar接口
package com.mayikt.v3.registry;
import com.mayikt.v3.entity.MemberEntity;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
/**
* @Description: 自定义手动注册类
* @Author: ChenYi
* @Date: 2020/07/03 07:48
**/
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(MemberEntity.class);
registry.registerBeanDefinition("memberEntity",rootBeanDefinition);
}
}
把自定义的ImportBeanDefinitionRegistrar注册到容器中
package com.mayikt.v3.config;
import com.mayikt.v3.registry.MyImportBeanDefinitionRegistrar;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* @Description: spring配置类
* @Author: ChenYi
* @Date: 2020/07/02 23:07
**/
@Configuration
@Import(MyImportBeanDefinitionRegistrar.class)
public class MySpringConfig {
}
FactoryBean和BeanFactory的区别
FactoryBean是往容器中注入对象,BeanFactory是从容器中获取对象,FactoryBean是个Bean,这个Bean不是简单的Bean而是一个能生产或者修饰对象生成的工厂Bean,在项目中基本用不到FactoryBean,手动注册,太麻烦了
下面展示一些 自定义FactoryBean
。
package com.mayikt.v3.factory;
import com.mayikt.v3.entity.DispacthEntity;
import org.springframework.beans.factory.FactoryBean;
/**
* @Description:
* @Author: ChenYi
* @Date: 2020/07/03 08:08
**/
public class MyFactoryBean implements FactoryBean<DispacthEntity> {
@Override
public DispacthEntity getObject() throws Exception {
return new DispacthEntity();
}
@Override
public Class<?> getObjectType() {
return DispacthEntity.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
package com.mayikt.v3.config;
import com.mayikt.v3.factory.MyFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Description: spring配置类
* @Author: ChenYi
* @Date: 2020/07/02 23:07
**/
@Configuration
public class MySpringConfig {
@Bean
public MyFactoryBean myFactoryBean() {
return new MyFactoryBean();
}
}
@Component
往spring容器中注入自定义的对象@Configuration 、@Repository、@Service、@Controller这几个注解底层都有引入这个@Component注解,把对象注入到spring容器中
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any
*/
String value() default "";
}
@Autowired
根据类型自动的注入对象,如果该类型对象是多个的时候可以结合@Qualifier注解指定的beanId
@Autowired
@Qualifier("userServiceImpl02")
private UserService userService;
@Resource
它不是Spring的注解,是JDK的注解。只能用在1.8以及以下的版本,在高的版本上取消了,默认按照类型去配,如果有多个相同的类型,可以指定name属性,去容器中id匹配
@Resource(name = "userServiceImpl02")
private UserService userService;