Spring注解开发
@Configuration
告诉spring这是一个配置类,配置类 = 配置文件
@Configuration
public class MainConfig {
}
@Bean
给容器注入一个bean
1).bean的类型为返回值类型,bean的名称默认是方法名
2).可以自定义bean的名称:@Bean("person")
3).下面的例子中,给容器MainConfig 注入一个Person,自定义名称为person
@Configuration
public class MainConfig {
@Bean("person") //自定义bean的名称为person
public Person person01() {
return new Person("lbl",35);
}
}
@Test
public void test() {
ApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
Arrays.stream(app.getBeanDefinitionNames()).forEach(System.out::println);
}
输入结果:
mainConfig
person
----------------------------------------------
小提示:@Configuratiion标注的配置类同时也是一个组件(@Configuratiion里面标注了@Component),所以也在输出结果中.
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
String value() default "";
}
@ComponentScan
定义扫描规则
例子:
@Configuration
@ComponentScan(value = "com.atguigu", useDefaultFilters = false,
includeFilters = {
// @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class,Repository.class}),
// @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {BookService.class}),
@ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyFilterType.class})
}
)
public class MainConfig {
@Bean("person")
public Person person01() {
return new Person("lbl",35);
}
}
@ComponentScan的属性说明
属性 | 返回类型 | 说明 |
value | String[] | 指定要扫描的包 |
useDefaultFilters | boolean | 指定过滤规则,默认的过滤规则是扫描所有(即会把标注了@Controller,@Service,@Repository,@Component 等等全部扫描),所以一般是设置为false |
excludeFilters | Filter[] | 指定扫描的时候按照什么规则排除那些组件 |
includeFilters | Filter[] | 指定扫描的时候只需要包含哪些组件 |
Filter[]的类型说明
类型 | 说明 |
FilterType.ANNOTATION | 按照注解 |
FilterType.ASSIGNABLE_TYPE | 按照给定的类型 |
FilterType.ASPECTJ | 使用aspectj表达式 |
FilterType.REGEX | 使用正则 |
FilterType.CUSTOM | 使用自定义规则 (当前扫描包下的所有类都会进行匹配) |
自定义TypeFilter指定过滤规则
自定义的类实现TypeFilter,重写match方法,在里面自定义过滤规则。
例子:
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;
import java.io.IOException;
public class MyFilterType implements TypeFilter {
//metadataReader: 读取到当前正在扫描的类的信息
//metadataReaderFactory:可以获取到其他任何的类的信息
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类的类信息(比如类的类型是什么,实现什么接口)
ClassMetadata classMetadata = metadataReader.getClassMetadata();
String className = classMetadata.getClassName();
//获取当前类资源(类的路径)
Resource resource = metadataReader.getResource();
//自定义过滤规则
if (className.contains("BookDao")) {
return true;
}
return false;
}
}
@Scope
设置组件作用域
singleton: 单例的(默认值)。ioc容器启动会调用方法创建对象放到ioc容器中,以后每次获取就是直接从容器中拿
prototype:多实例的。ioc容器启动并不会去调用方法创建对象放在容器中,每次获取的时候才会调用方法创建对象
request: 同一次请求创建一个实例
session: 同一个session创建一个实例
例子:
@Scope("prototype")
@Bean("person")
public Person person01() {
return new Person("lbl",35);
}
@Lazy
懒加载
单实例bean:默认在容器启动的时候创建对象;
加上@Lazy:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
例子:
@Lazy
@Bean("person")
public Person person(){
return new Person("lbl", 35);
}
@Conditional
按照条件注册bean
@Conditional 放在类上,表示满足当前条件,这个类上配置的所有bean注册才能生效。
自定义的类实现Condition
@Bean("linus")
@Conditional(LinuxCondition.class)
public Person person02(){
return new Person("linus", 48);
}
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
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.util.Arrays;
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment env = conditionContext.getEnvironment();
//获取操作系统名称
String osName = env.getProperty("os.name");
if (osName.contains("linux")) {
return true;
}
return false;
}
}