Spring 注解版
@Bean — 组件注册
对于一个普通的bean: Person
package com.spring.annotation.bean;
public class Person {
private String name;
private Integer age;
getter() setter()...
}
-
传统方式–配置文件
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="person" class="com.spring.annotation.bean.Person"> <property name="name" value="Sairo"></property> <property name="age" value="18"></property> </bean> </beans>
-
测试类
采用配置文件的方式时创建ClassPathXmlApplicationContext对象
public class XMLTest { @Test public void test00() { ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); Person person = (Person) context.getBean("person"); System.out.println(person); } }
-
注解方式–配置类
当采用注解方式时,需要编写一个用@Configutation标记的类作为配置类,用来取代配置文件
MainConfig
/** * 配置类代替了配置文件 * @Configuration: 告诉Spring这是一个配置类 */ @Configuration public class MainConfig { /** * @Bean: 取代了 <bean><bean/> 标签 * 给容器中注册一个bean, id默认是方法名 */ @Bean public Person person() { return new Person(); } }
-
测试类
采用注解方式时,要创建AnnotationConfigApplicationContext实例,传入配置类的class对象
public class AnnotationTest { @Test public void test00() { ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class); Person person = (Person) context.getBean("person"); System.out.println(person); } }
-
更改bean在容器中的名字
-
修改配置类中的方法的名称
public Person person01() { return new Person("LiSi", 20); }
-
在@Bean注解中通过value属性指定名字
@Bean(value="person01") public Person person() { return new Person("LiSi", 20); }
-
测试
@Test public void test01() { ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class); Person person = (Person) context.getBean("person"); System.out.println(person); // 查看bean在Spring容器中的名字 String[] beanNames = context.getBeanNamesForType(Person.class); for (String beanName : beanNames) { System.out.println(beanName); } }
-
@ComponentScan — 包扫描
包扫描是用于扫描指定包(及其子包)下的标注了@Controller, @Service, @Repository, @Component注解的类,并将它们加载到Spring容器中
-
配置文件方式
<!-- 包扫描, 用于扫描指定包(及其子包)下的标注了@Controller, @Service, Repository, @Component注解的类, 将其加载到容器中 --> <context:component-scan base-package="com.lymboy.spring" ></context:component-scan>
-
注解方式
标注在MainConfig配置类上(头部)
@ComponentScan(value = "com.lymboy.spring")
-
测试
public class IOCTest { private ApplicationContext applicationContext; @Before public void init() { applicationContext = new AnnotationConfigApplicationContext(MainConfig.class); } @Test public void test01() { int count = applicationContext.getBeanDefinitionCount(); String[] names = applicationContext.getBeanDefinitionNames(); System.out.println(count+": "); for (String name : names) { System.out.println(name); } } }
@ComponentScan属性详解
-
value: 用来指定扫描的包
@ComponentScan(value = "com.lymboy.spring")
-
useDefaultFilters: 使用默认扫描规则, 全部扫描
@ComponentScan(value = "com.lymboy.spring" useDefaultFilters = false) // 关闭
-
excludeFilters: 用来排除不需要的类
Filter[] excludeFilters() default {};
@ComponentScan(value = "com.lymboy.spring", excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = { Controller.class, Service.class}) })
参数是一个 @Filter数组
- type: 指定过滤方式 默认是 FilterType.ANNOTATION(注解)方式 (FilterType type() default FilterType.ANNOTATION;), 选择按注解类型过滤时, 在value中指定的包(及其子包)下的所有在classes(下面的这个属性)中指定的注解都不会被扫描
- classes数组: 指定过滤的类型 . 如果是按注解过滤, 则classes中填注解类型
-
includeFilters: 仅加载指定的类, 首先要禁用默认扫描规则, 使用方法与上面的excludeFilters相同, 作用相反
@ComponentScan(value = "com.lymboy.spring", useDefaultFilters = false, includeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = { Controller.class, Service.class}) })
过滤规则 FilterType
用来指定包扫描的过滤规则
public enum FilterType {
// 注解方式 常用
ANNOTATION,
// 按照给定的类型 常用
ASSIGNABLE_TYPE,
// 不常用
ASPECTJ,
// 使用正则表达式
REGEX,
// 用户自定义
CUSTOM
}
-
FilterType.ANNOTATION :
-
FilterType.ASSIGNABLE_TYPE : 与 FilterType.ANNOTATION 相似, 前者在classes属性中填 类的类型, 后者填注解的类型
-
FilterType.REGEX : 通过正则表达式过滤
@ComponentScan(value = "com.lymboy.spring", useDefaultFilters = false, includeFilters = { @ComponentScan.Filter(type = FilterType.REGEX, pattern = { ".*Service"}) })
-
FilterType.CUSTOM : 通过实现 org.springframework.context.annotation.FilterType 接口, 自定义规则
MyTypeFilter :自定义的类,实现了 FilterType 接口
@ComponentScan(value = "com.lymboy.spring", useDefaultFilters = false, includeFilters = { @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class}) })
package com.lymboy.spring.annotation.config;
public class MyTypeFilter implements TypeFilter {
/**
* @param metadataReader: 用来读取当前正在扫描的类的信息
* @param metadataReaderFactory: 用来访问其他类的信息
* @return
* @throws IOException
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
Resource resource = metadataReader.getResource();
String filename = resource.getFilename();
if (filename.contains("Service")) {
return true;
}
return false;
}
}
过滤方式 | 表达格式 |
---|---|
FilterType.ANNOTATION | classes 属性中填入需过滤的注解的class对象 |
FilterType.ASSIGNABLE_TYPE | classes属性中填入需过滤的类的class对象 |
FilterType.REGEX | pattern 属性中填入对应的正则表达式 |
FilterType.CUSTOM | 实现 FilterType 接口 |
@Scope — 作用域
-
@Scope : 用于设定 bean 的作用范围, 即单实例还是多实例
- @scope 注解添加在@Bean注解添加的地方, 一般是bean上
@Configuration<