Spring是一个综合性的开发框架,旨在简化Java应用程序的开发过程。它提供了广泛的功能,包括依赖注入、面向切面编程、事务管理、数据访问等,使开发人员能够更专注于业务逻辑而不必过多关注底层的技术细节。Spring的模块化结构允许开发者选择并使用其中需要的部分,从而实现更轻量级的应用程序。此版本是spring5.2.9
spring的两个核心概念IOC及AOP
- ioc:控制反转,对象的创建以及依赖关系交给容器处理,DI依赖注入是实现手段。
- aop:面向切面编程,在程序中插入切面来提高模块化和代码复用性。
spring的使用
<beans>
<bean id=? class=? abstract init-method scope depends on .. >
<property name = ? value=? />
<property name = ? ref=? />
</bean>
<bean id=? class=? abstract init-method scope depends on .. >
<property constractor-arg= ? value=? />
<property constractor-arg= ? ref=? />
</bean>
</beans>
ApplicationContext ac = new ClassParhApplicationContext(application.xml);
//①
XXX xxx= ac.getBean(xxx.class);
xxx.method();
下面分析①的对象是怎么拿到的?
- 加载xml
- 解析xml
- 封装beanDefinition
- 实例化
- 放到容器里
- 从容器中获取
容器使用的是Map结构的,包含这几种类型<String,Object>、<Class,Object>、<String,ObjectFactory>、<String,BeanDefination>
总体流程图
beanFactoryPostProcessor和beanPostProcessor的区别
- beanFactoryPostProcessor增强beanDefinition信息
- beanPostProcessor增强bean信息
beanFactoryPostProcessor
动态改变bean的定义信息,如果想随时修改bean定义,就会使用到beanFactoryPostProcessor
<property name = url value = ${jdbc.url}>
//用于解析bean定义中属性值里面的占位符,此类不能被直接实例化使用
public abstract class PlaceholderConfigurerSupport extends PropertyResourceConfigurer
implements BeanNameAware, BeanFactoryAware {
/**
* 默认的占位符前缀
*
* Default placeholder prefix: {@value}. */
public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";
/**
* 默认的占位符后缀
*
* Default placeholder suffix: {@value}. */
public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";
/**
* 默认的值分隔符
*
* Default value separator: {@value}. */
public static final String DEFAULT_VALUE_SEPARATOR = ":";
//省略部分代码。。。
}
修改bean定义的属性
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition def = beanFactory.getBeanDefinition("a");
def.setLazyInit(xx);
def.setScope(xx);
def.setDependsOn(xx);
//...
}
}
实例化与初始化
- 实例化在堆中开辟一块空间,对象的属性值都是默认值。
- 初始化给属性设置值,填充属性,执行初始化方法init-method,常见的初始化配置集合。
实例化初始化之后完成对象的创建。
public class A {
public void init(){
System.out.println("init");
System.out.println(this.name);
}
//省略部分代码 。。。
}
<bean id="a" class="com.mashibing.cycle.A" init-method="init >
<property name="name" value="zhangsan"></property>
</bean>
Aware接口的作用
当Spring容器创建的bean对象在进行具体操作的时候,如果需要容器的其他对象,此时可以将对象实现Aware接口,来满足当前的需要,比如beanNameAware,ApplicationContextAware,EnvironmentAware。
public interface Aware {
}
public class A implements ApplicationContextAware{
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
}
ApplicationContext ac = new ClassParhApplicationContext(application.xml);
A bean= ac.getBean(A.class);
bean.getApplicationContext();
BeanPostProcessor
动态代理类就是实现了bean后置处理器的后置方法
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
//省略部分代码
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 获取当前bean的key:如果beanName不为空,则以beanName为key,如果为FactoryBean类型,
// 前面还会添加&符号,如果beanName为空,则以当前bean对应的class为key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 判断当前bean是否正在被代理,如果正在被代理则不进行封装
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 如果它需要被代理,则需要封装指定的bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
//省略部分代码
}
两类spring对象
springBean:一类是容器需要的对象,一类是普通对象我们自定义需要的对象。