Spring的两个核心理念:
- 一个是控制反转(Inversion of Control, IoC)
- 另一个是面向切面编程(Aspect Oriented Programming, AOP)
IoC是一和通过描述生成或者获取对象的技术。Springboot不建议使用XML,而是通过注解的描述生成对象。
IoC容器需要具备两个基本功能:
- 通过描述管理Bean,包括发布和获取Bean
- 通过描述完成Bean之间的依赖关系。
IoC容器简介
Sping IoC是管理Bean的容器。Spring要求所有的IoC容器都需要实现BeanFactory。
源码BeanFactory接口中,可以知道,Spring IoC容器中,允许我们按类型或者名称获取Bean。
其中,isSingleton方法判断Bean是否在Spring IoC中为单例的。默认司下,Bean 都是单例存在的,也主是使得getBean方法返回都是同一个对象。
与isSingleton方法相反的是isProtorype方法,如果它返回的是ture,那么getBean方法获取Bean是,容器将创建一个新的Bean返回给调用者。
public class AppConfig {
@Bean(name = "user")
public User initUser() {
User user = new User();
user.setId(1L);
user.setUserName("user_name_1");
user.setNote("note_1");
return user;
}
}
@Configuration 代表这是一个Java配置文件,Spring的容器会根据它来生成IoC容器去装配 Bean;@Bean 代表将initUser方法返回的POJO装配到IoC容器中,而其属性name定义这个Bean名称,如果没有配置它,则将方法名称"initUser" 作为Bean的名称保存到Spring IoC容器中。
装配你的Bean
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.context.annotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
// 在一个类中可重复定义
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
// 定义扫描的包
@AliasFor("basePackages")
String[] value() default {};
// 定义扫描的包
@AliasFor("value")
String[] basePackages() default {};
// 定义扫描的类
Class<?>[] basePackageClasses() default {};
// Bean name 生成器
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
// 作用域解析器
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
// 作用代理模式
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
// 资源匹配模式
String resourcePattern() default "**/*.class";
// 是否启动默认过滤器
boolean useDefaultFilters() default true;
// 当满足过滤器条件时扫描
ComponentScan.Filter[] includeFilters() default {};
// 当不满足过滤器条件时扫描
ComponentScan.Filter[] excludeFilters() default {};
// 是否延迟初始化
boolean lazyInit() default false;
// 定义过滤器
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Filter {
FilterType type() default FilterType.ANNOTATION;
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
String[] pattern() default {};
}
}
- 可以通过配置项basePackages定义扫描包名,在没有定义的情况下,它只会扫描当前包和其子包下的路径
- 可以通过basePackageClasses定义扫描的类
- 还有includeFilters 和 excludeFilters
- includeFilters是定义满足过滤器(Filter)条件的Bean才去扫描
- excludeFilters是排除过滤器条件的Bean。
- 它们都需要通过@Filter去定义,它有一个type类型,这里可以定义为注解或者正则式等类型。
@Component("user")
public class User {
@Value("1")
private Long id;
@Value("user_name_1")
private String userName;
@Value("note_1")
private String note;
}
@ComponentScan("com.springboot.chapter3.*")
@ComponentScan(basePackages = {"com.springboot.chapter3.pojo"})
@ComponentScan(basePackageClasses = {User.class})
public class AppConfig {
}
上述三种方式都能够使用IoC容器去扫描User类,而包名可以采用正则式去匹配。
@ComponentScan(basePackages = “com.springboot.chapter3.*”, excludeFilters = {@ComponentScan.Filter(classes = {Service.class