Spring IOC
Sping最成功的是其提出的理念,而不是技术本身。它所依赖的两个核心的理念,一个是控制反转(Inversion of Control,IOC),另一个是面向切面编程(Aspect Oriented Programming,AOP)。
IOC容器是Spring的核心,可以说Spring是一种基于IoC容器编程的框架。
IoC以一种通过描述来生成或者获取对象的技术。在Spring中把每一个需要管理的对象称为Spring Bean(简称Bean),而Spring管理这些Bean的容器,被称为IoC容器。
IoC容器需要具备两个基本功能:
- 通过描述管理Bean,包括发布和获取Bean;
- 通过描述完成Bean间的依赖关系。
IoC容器简介
Spring IoC容器是一个管理Bean的容器,在Spring的定义中,他要求所有的IoC容器都需要实现接口BeanFactory,他是一个顶级容器接口。
源码中多个getBean方法,IoC容器中允许我们按照类型或者名称获取Bean。
isSingleton方法则判断Bean是否存在Spring IoC中为单例。默认情况下,Bean是以单例存在的,也就是使用getBean方法返回的都是同一个对象。
与isSingleton方法相反的是isPrototype方法,如果它返回的是true,那我们使用getBean方法获取Bean的时候,Spring IoC容器就会创建一个新的Bean返回给调用者。
由于BeanFactory的功能不够强大,因此Spring在BeanFactory的基础上,还设计了一个更为高级的接口ApplicationContext。它是BeanFactory的子接口之一,在Spring体系中,
BeanFactory和ApplicationContext是最为重要的接口设计,在现实中我们使用的大部分Spring IoC容器是ApplicationContext接口的实现类。
如图,ApplicationContext接口通过继承上级接口,进而继承BeanFactory接口,但是在BeanFactory的基础上,扩展了消息国际化接口(MessageSource),环境可配置接口(EnvironmentCapable),应用事件发布接口(ApplicationEventPublisher)
和资源模式解析接口(ResourcePatterResolver),所以他的功能会更为强大。
在Sping boot中我们主要是通过注解来装配Bean到Spring IOC 容器中,AnnotationConfigApplicationContext是一个基于注解的IOC容器,一个基于注解的IoC容器,Spring Boot装配和获取Bean的方法与他相同。
首先创建一个java对象:
public class User {
private Long id;
private String userName;
private String note;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
然后再定义一个Java配置文件AppConfig.java
@Configuration
public class AppConfig {
@Bean(name = "user")
public User initUser() {
User user = new User();
user.setId(1L);
user.setUserName("kangjie");
user.setNote("note_1");
return user;
}
}
@Configuration代表这是一个Java配置文件,Spring容器会根据它来生成IOC容器去装配Bean;
@Bean代表将initUser方法返回POJO装配到IOC容器中,而其属性name定义这个Bean的名称,如果没有配置name,则方法将命名为“initUser”作为Bean的名称保存到IOC容器中。
做好了这些就可以使用AnnotationConfigApplicationContext来构建自己的IOC容器:
public class IoCTest {
private static Logger logger = LoggerFactory.getLogger(IoCTest.class);
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
User user = ctx.getBean(User.class);
logger.info("=====" + user.getUserName());
}
}
代码将Java配置文件AppConfig传递给AnnotationConfigApplicationContext的构造方法,这样就能够读取配置了。然后将配置里面的Bean装配到IOC容器中,于是就可以使用getBean方法获取对应的POJO了。
spring可以使用@Component和@ComponentScan进行装配扫描
1.3 自定义第三方Bean
引入一个DBCP数据源,在pom.xml文件中加入依赖:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
然后使用DBCP生成数据源
@Bean(name="dataSource") public DataSource getDataSource(){ Properties props = new Properties(); props.setProperty("driver","com.mysql.jdbc.Driver"); props.setProperty("url","jdbc:mysql://localhost:3306/abc"); props.setProperty("username","root"); props.setProperty("password","123456"); Datasource dataSource = null; }
这里通过@Bean定义了其配置项name为"dataSource",那么spring就会把他返回的对象用名称"dataSource"保存到IOC容器中。
1.4 依赖注入