目录
启动注解驱动
<context:component-scan base-package="com.itheima"/>
在spring中,对所有spring加载的资源统称为component
在spring中,对所有spring加载的资源统称为component
注册bean
@Component @Controller @Service @Repository
属性 | |
---|---|
id | value(默认):定义bean的访问id |
class | |
@scope | value(默认):定义bean的作用域,默认为singleton |
init-method | @PostConstruct |
destrop-method | @PreDestroy |
@Autowired默认按类型装配,当出现相同类型的bean,
使用@Primary提高按类型自动装配的优先级,多个@Primary会导致优先级设置无效
注解配置第三方资源(工厂加载bean的形式)
@Bean |
---|
@Bean所在的类必须被spring扫描加载,否则该注解无法生效 |
@Bean 用在方法上,告诉Spring容器,你可以从下面这个方法中拿到一个Bean |
该注解用于替代XML配置中的静态工厂与实例工厂创建bean,不区分方法是否为静态或非静态 |
value(默认):定义bean的访问id |
例子
//@Bean所在的类可以使用导入的形式进入spring容器,无需声明为bean
public class JDBCConfig {
@Bean("dataSource")
public static DruidDataSource getDataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/db1");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
}
bean属性注入
非引用类型属性注入 | |
---|---|
@Value | @Autowired + @Qualifier |
属性注解、方法注解 | 属性注解、方法注解 |
设置对应属性的值或对方法进行传参 | 设置对应属性的对象或对方法进行引用类型传参 |
@Autowired默认按类型装配、按名装配 required:定义该属性是否允许为null | |
@Qualifier后可以指定自动装配的bean的id | |
所谓装配,就是管理对象直接的协作关系 |
加载properties文件
@PropertySource | 加载properties文件中的属性值 |
---|---|
类注解 | |
value | 设置加载的properties文件名 |
ignoreResourceNotFound | 如果资源未找到,是否忽略,默认为false |
@Component("userService")
@PropertySource(
value = {"classpath:jdbc.properties","classpath:abc.properties"},
ignoreResourceNotFound = true)
public class UserServiceImpl implements UserService {
@Value("${jdbc.username}")
private String name;
@Value("${jdbc.password}")
private String psw;
}
纯注解驱动制作
@Configuration | 设置当前类为spring核心配置加载类 |
---|---|
类注解 | |
@ComponentScan | bean扫描工作使用 |
类注解 |
加载纯注解格式上下文对象,需要使用AnnotationConfigApplicationContext
@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}
第三方bean配置与管理
@Import | 导入第三方bean作为spring控制的资源 |
---|---|
类注解 | |
@Bean所在的类可以使用导入的形式进入spring容器,无需声明为bean |
@Import({JDBCConfig.class,abc.class})
public class SpringConfig {
}
细节:加载控制
@DependsOn | @Order() |
---|---|
value 设置当前bean所依赖的bean的id | @Order(1)、@Order(2) ... |
类注解、方法注解 | 配置类注解 |
bean定义的位置(类上或方法上) | 配置类定义的位置(类上) |
控制bean的加载顺序,使其在指定bean加载完毕后再加载 | 控制配置类的加载顺序 |
组件扫描器
开发过程中,需要根据需求加载必要的bean,排除指定bean
@ComponentScan |
---|
类注解 |
设置spring配置加载类扫描规则 |
自定义组件过滤器 implements TypeFilter |
测试类注意
@ContextConfiguration
这个注解通常与@RunWith(SpringJUnit4ClassRunner.class)
联合使用用来测试当一个类添加了注解
@Component
,那么他就自动变成了一个bean,就不需要再Spring配置文件中显示的配置了。把这些bean收集起来通常有两种方式,Java的方式和XML的方式。当这些bean收集起来之后,当我们想要在某个测试类使用
@Autowired
注解来引入这些收集起来的bean时,只需要给这个测试类添加@ContextConfiguration
注解来标注我们想要导入这个测试类的某些bean。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testSave(){
userService.save();
}
}
@Configuration
//@ComponentScan("com.itheima")
//1.设置排除bean,排除的规则是注解修饰的(FilterType.ANNOTATION)的bean,具体的注解为(Service.class)
/*
@ComponentScan(
value = "com.itheima", //设置基础扫描路径
excludeFilters = //设置过滤规则,当前为排除过滤
@ComponentScan.Filter( //设置过滤器
type= FilterType.ANNOTATION, //设置过滤方式为按照注解进行过滤
classes = Service.class //设置具体的过滤项,过滤所有@Service修饰的bean
)
)
*/
//2.设置排除bean,排除的规则是自定义规则(FilterType.CUSTOM),具体的规则定义为(MyTypeFilter.class)
/*
@ComponentScan(
value = "com.itheima",
excludeFilters = @ComponentScan.Filter(
type= FilterType.CUSTOM,
classes = MyTypeFilter.class
)
)
*/
//3.自定义导入器
//@Import(MyImportSelector.class)
public class SpringConfig {
}
自定义组件过滤器
public class MyTypeFilter implements TypeFilter {
@Override
//加载的类满足要求,匹配成功
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//通过参数获取加载的类的元数据
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//通过类的元数据获取类的名称
String className = classMetadata.getClassName(); //spring加载的全部东西
//如果加载的类名满足过滤器要求,返回匹配成功
if(className.equals("com.itheima.service.impl.UserServiceImpl")){
//返回true表示匹配成功,返回false表示匹配失败。此处仅确认匹配结果,不会确认是排除还是加入,排除/加入由配置项决定,与此处无关
return true;
}
return false;
}
}
自定义导入器
ImportSelector | 自定义bean导入器 |
---|---|
接口 |
bean只有通过配置才可以进入spring容器,被spring加载并控制
配置bean的方式如下:
XML文件中使用
标签配置 使用@Component及衍生注解配置
导入大量的bean 取代配置bean,类不需要配置了
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// 1.编程形式加载一个类
// return new String[]{"com.itheima.dao.impl.BookDaoImpl"};
// 2.加载import.properties文件中的单个类名
// ResourceBundle bundle = ResourceBundle.getBundle("import");
// String className = bundle.getString("className");
// 3.加载import.properties文件中的多个类名
ResourceBundle bundle = ResourceBundle.getBundle("import");
String className = bundle.getString("className");
return className.split(",");
}
}
使用
@Configuration
@ComponentScan("com.itheima")
//3.自定义导入器
@Import(MyImportSelector.class)
public class SpringConfig {
}
改进properties
path=com.itheima.dao.impl.*
自定义注册器
模拟@ComponentScan
ImportBeanDefinitionRegistrar | 自定义bean定义注册器 |
---|---|
接口 |
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//自定义注册器
//1.开启类路径bean定义扫描器,需要参数bean定义注册器BeanDefinitionRegistry,需要制定是否使用默认类型过滤器
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry,false);
//2.添加包含性加载类型过滤器(可选,也可以设置为排除性加载类型过滤器)
scanner.addIncludeFilter(new TypeFilter() {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//所有匹配全部成功,此处应该添加实际的业务判定条件
return true;
}
});
//设置扫描路径
scanner.scan("com.itheima");
}
}
使用
@Configuration
//@ComponentScan("com.itheima")
//4.自定义注册器
@Import(MyImportBeanDefinitionRegistrar.class)
public class SpringConfig {
}