Spring框架中配置类分为申明式和注解式。
前者通过写xml然后设置<bean>xxx</bean>
标签为bean赋值;后者通过注解annotation方式为bean赋值。
注解方式
@Bean
创建Maven工程然后引入Spring的基本第三方库
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring-learn</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
</dependencies>
</project>
创建JavaBean:Person类
package my.spring.test1.config;
public class Person {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
配置 MainConfig 类
@Configuration
public class MainConfig {
// 定义一个bean,类型为return的类的类型;bean的id默认是方法名,否则是注解里的参数
@Bean
public Person person2() {
return new Person("Tom", 15);
}
}
创建MainTest类,并获取Spring上下文Context
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
Person bean = context.getBean(Person.class);
System.out.println(bean);
for (String name : context.getBeanDefinitionNames()) System.out.println(name);
}
}
运行MainTest类输出
Person{name='Tom', age=15}
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
person2
@Service或者@Controller或者@Component
在要导入的bean的类上直接加这三个注解之一就可以了。
小结
@Bean这种方式适合导入第三方的Bean,而@Service或者@Controller或者@Component适合导入自己写的类
@ComponentScan/ComponentScans
定义两个bean的类,Keeper和Student
@Service
public class Keeper {
}
@Controller
public class Student {
}
编写配置类MainConfig2将包:my.spring.test2下的Keeper和Student类加入IOC容器
@ComponentScan(value = "my.spring.test2"
, includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Service.class})}
, useDefaultFilters = false)
public class MainConfig2 {
}
如果使用includeFilters 这个参数表示要将包下的这些类加入IOC容器,同时useDefaultFilters 参数必选false。
也可以设置excludeFilters 参数表示不加入IOC容器的类
@ComponentScan(value = "my.spring.test2"
, excludeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})})
public class MainConfig2 {
}
其中如果Filter参数的type值设置为FilterType.CUSTOM表示采用自定义的拦截器类设置包下哪些类要加入IOC容器
编写MyTypeFilter类
public class MyTypeFilter implements TypeFilter {
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
// 返回true表示加入IOC容器,false表示不加入
ClassMetadata classMetadata = metadataReader.getClassMetadata();
String className = classMetadata.getClassName();
System.out.println("MyTypeFilter -> " + className);
if ("my.spring.test2.Keeper".equals(className)) return true;
return false;
}
}
创建测试主类ComponentScanTest
public class ComponentScanTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig2.class);
for (String dname: context.getBeanDefinitionNames()) System.out.println(dname);
}
}
输出:
前四行表示经过拦截器过滤后的类
MyTypeFilter -> my.spring.test2.ComponentScanTest
MyTypeFilter -> my.spring.test2.Keeper
MyTypeFilter -> my.spring.test2.MyTypeFilter
MyTypeFilter -> my.spring.test2.Student
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
student
也可以通过ComponentScans注解设置多个包路径……
public @interface ComponentScans {
ComponentScan[] value();
}