Spring核心

Spring核心思想

Spring的核心是为Class创建代理对象实现一些AOP切面操作,从而支持方便的注解、事务、自动注入等功能。
为了创建代理对象,需要将对象创建移交给Spring完成,因此需要IoC容器。

IoC

Inversion of Control
Spring通过控制反转,将对象创建交给IoC容器完成。
IoC容器实际上就是一个工厂,通过读取xml配置文件,使用反射创建对象。

<bean id="userDao" class="com.site.UserDao"></bean>
class UserFactory {
public static UserDao getDao() {
String classValue = context.getProperty("userDao");
Class clazz = Class.forName(classValue);
}
}

当我们的Dao文件路径改变时,只需要修改xml配置一处即可完成全部修改。
如果只用工厂模式,那需要导入很多包,也不直观。因此使用xml与反射,将工厂方法与配置解耦。

  • BeanFactory:IoC容器基本使用,Spring内部使用
    对象懒创建
  • ApplicationContext:BeanFactory子接口,暴露给开发者使用
    加载配置就会创建对象

Bean生命周期

类class -> 无参构造方法 -> 普通对象 -> 依赖注入 -> "@PostConstruct" -> 初始化 -> AOP -> 代理对象 -> Bean

Spring Framework

AnnotationConfigApplicationContext context = 
new AnnotationConfigApplicationContext(AppConfig.class);
// resource/application.xml
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("application.xml")

UserService userService = (UserService) context.getBean("userService");

Dependency Injection

Spring首先是调用对象自身的构造方法创建对象,然后通过依赖注入(@Autowired属性赋值)来得到Bean

for (Field field: userService.getClass().getFields()) {
if (field.isAnnotationPresent(Autowired.class)) {
field.set(userService, value);
}
}

PostConstruct

这个注解可以让Spring在初始化时调用此方法,从而实现一些初始化操作(如从数据库查询信息映射到实体类)。

@PostContruct
public init() {
...
}

for (Method method: userService.getClass().getMethods()) {
if (method.isAnnotationPresent(PostConstruct.class)) {
method.invoke(userService, null);
}
}

AOP

AOP后,得到一个代理对象,然后Spring会在代理对象内部增加一个属性UserService target,并将经过依赖注入的普通对象赋值给target,然后调用target.method(),从而保留对象的所有Field的同时,可以通过代理在切面上做一些额外操作。