1.创建maven项目,引入需要的jar包。
贴上对应的pom.xml内容
<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>SpringDemo</groupId>
<artifactId>SpringDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
</dependencies>
</project>
2.spring在最早期的时候是通过xml配置在实例化bean的。
a.在classpath下创建bean.xml文件
b.通过bean.xml生成ioc容器
c.通过容器获得实例化的对象
public class Person {
private String name;
private Integer age;
public Person() {
}
public Person(final String name, final Integer age) {
super();
this.name = name;
this.age = age;
}
public Integer getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(final Integer age) {
this.age = age;
}
public void setName(final String name) {
this.name = name;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
2.创建 bean.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.erwan.cap1.Person">
<property name="name" value="erwan"></property>
<property name="age" value="19"></property>
</bean>
</beans>
3.测试类
ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
System.out.println(app.getBean("person"));
4.测试结果
Person [name=erwan, age=19]
3.在后面的版本spring使用注解来达到目的,推荐使用注解。
@Bean
其中如果@Bean后面跟了名称"erwan",则bean名称为erwan。如果没有跟,就是方法名称person
1.创建一个配置类,写上注解
@Configuration
public class Cap1MainConfig {
@Bean("erwan")
public Person person() {
return new Person("erwan", 20);
}
}
2.测试类,把配置类加入ioc容器,通过容器得到对应的bean
AnnotationConfigApplicationContext context =
AnnotationConfigApplicationContext(Cap1MainConfig.class);
System.out.println(context.getBean("erwan"));
3.测试结果
Person [name=erwan, age=19]
@ComponentScans与@ComponentScan
顾名思义,也就是组件扫描,@ComponentScans也就是里面可以放很多@ComponentScan
下面我们介绍@ComponentScan,它里面有很多属性:
value:指明扫描哪些包,扫描的意思就是把所有具有注解的类都注册到ioc容器中(比如说 @Controller,@Service,@Repository等),待会儿我们来来看com.erwan.cap2下有什么
includeFilters 就是指明只扫指定@Filter的内容,@Filter就是一个一个的筛选器。
excludeFiters和includeFilters正好相反,不扫指定@Filter的内容
userDefaultFilters这里表明是否使用spring默认的筛选器。
接下来看实际操作结果:
定义配置类:
@Configuration
@ComponentScans(value = { @ComponentScan(value = "com.erwan.cap2", includeFilters = {
@Filter(type = FilterType.ANNOTATION, classes = Controller.class) }
, useDefaultFilters = false) })
public class Cap2MainConfig {
@Bean("erwan")
public Person person() {
return new Person("erwan", 20);
}
}
在com.erwan.cap2包下新建两个类
//类OrderController
@Controller
public class OrderController {
}
//类 OrderService
@Service
public class OrderService {
}
新建测试类
@Test
public void cap2() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Cap2MainConfig.class);
// 获取容器中 所有的beanName
String[] beanNames = context.getBeanDefinitionNames();
for (String name : beanNames) {
System.out.println(name);
}
}
测试结果:
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
cap2MainConfig
orderController
erwan
从测试结果上来看 除了spring自带的一些bean和配置类cap2MainConfig还有配置类中的bean,就只扫描了@Controller的类,也就是orderController,并没有扫描和注册orderServcie。把includeFilters换成excludeFilters会得到相反的结果
接下来我们分析@Filter这个注解,它的type属性有多个选项包括
ANNOTATION,//注解
ASSIGNABLE_TYPE,//指定类型 比如说指定@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = OrderService.class)
ASPECTJ,//切面
REGEX,
CUSTOM//定制 ,使用自己定义的筛选器 比如@Filter(type = FilterType.CUSTOM, classes = ErwanTypeFilterType.class)
可以定制自己的筛选器
public class ErwanTypeFilterType implements TypeFilter {
public boolean match(final MetadataReader reader, final MetadataReaderFactory factory) throws IOException {
AnnotationMetadata meta = reader.getAnnotationMetadata();
ClassMetadata classMetadata = reader.getClassMetadata();
String className = classMetadata.getClassName();
if (className.contains("OrderController")) {
return true;
}
return false;
}
}
@Scope,指明该bean是单例还是多例,默认单例
@Scope("prototype") 则是多例
* scope四种类型:
* 1:prototype,多例,在容器使用的该bean的时候才会创建
* 2:sigleton,单例,容器会在初始化的时候,就会创建对象,在调用对象的时候,直接从容器中拿
* 3.request,针对web请求,调用一次,创建一个实例
* 4.session ,同一个session创建一个实例
@Lazy 懒加载,在ioc中先定义好bean的信息,并不创建,在调用对象的时候才创建。
@Conditional 按照条件加载
@Configuration
public class Cap5MainConfig {
@Bean("erwan")
@Conditional(WindowCondition.class)
public Person person() {
return new Person("erwan", 20);
}
}
public class WindowCondition implements Condition {
public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if (property.contains("linux")) {
return true;
}
return false;
}
}
@Value的使用
在src/main/resources下创建bird.properites文件里面内容为:bird.name=erwan
创建bird类
public class Bird {
@Value("red")
private String color;
@Value("${bird.name}")
private String name;
@Value("#{20-2}")
private Integer age;
public String getColor() {
return color;
}
public String getName() {
return name;
}
public void setColor(final String color) {
this.color = color;
}
public void setName(final String name) {
this.name = name;
}
@Override
public String toString() {
return "Bird [age="+age+",color=" + color + ", name=" + name + "]";
}
}
创建配置类
@Configuration
@PropertySource("classpath:/bird.properities")
public class Cap8MainConfig {
@Bean
public Bird bird() {
return new Bird();
}
}
创建测试类
@Test
public void cap8() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Cap8MainConfig.class);
Object bean = context.getBean("bird");
System.out.println(bean);
ConfigurableEnvironment environment = app.getEnvironment();
System.out.println("environment===="+environment.getProperty("bird.color"));
context.close();
}
测试结果是
Bird [age=18,color=red, name=erwan]
environment=red
其中@PropertySource("classpath:/bird.properities")引入bird.peroerities,通过${bird.properities}引入值到 color中
属性文件的值存在环境变量environment中的
@value还支持表达式