实现简单的Spring的Ioc容器,包含容器初始化,Bean实例化,实现@Service、@Autowired、@Transactional、@Bean、@Value等注解
IoC Inversion of Control (控制反转/反转控制),它是⼀个技术思想,不是⼀个技术实现
描述的事情:Java开发领域对象的创建,管理的问题
传统开发⽅式:⽐如类A依赖于类B,往往会在类A中new⼀个B的对象
IoC思想下开发⽅式:我们不⽤⾃⼰去new对象了,⽽是由IoC容器(Spring框架)去帮助我们实例化对象并且管理它,我们需要使⽤哪个对象,去问IoC容器要即可
我们丧失了⼀个权利(创建、管理对象的权利),得到了⼀个福利(不⽤考虑对象的创建、管理等⼀系列事情)
为什么叫做控制反转?
控制:指的是对象创建(实例化、管理)的权利
反转:控制权交给外部环境了(spring框架、IoC容器)
IoC解决对象之间的耦合问题
IOC和DI描述的是同⼀件事情,只不过⻆度不⼀样
AOP: Aspect oriented Programming ⾯向切⾯编程/⾯向⽅⾯编程
AOP是OOP的延续,从OOP说起
OOP三⼤特征:封装、继承和多态
OOP是⼀种垂直继承体系,而AOP是一种纵向的体系
比如:想在多个业务方法运行前后记录日志,为了不影响业务代码那么就抽象出一个横切逻辑单读维护
案例实现了IOC容器的管理,包含容器初始化,Bean实例化,实现@Service、@Autowired、@Transactional、@Bean、@Value等注解,其中@Transactional就属于AOP的一种实现(动态代理)
<dependencies>
<!-- 单元测试Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- mysql数据库驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!--druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jackson依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
<!--dom4j依赖-->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!--xpath表达式依赖-->
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
</dependency>
<!--引入cglib依赖包-->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_2</version>
</dependency>
</dependencies>
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ozdemo?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for account
-- ----------------------------
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
`aid` int(11) NOT NULL AUTO_INCREMENT,
`cardNo` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`money` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`aid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of account
-- ----------------------------
INSERT INTO `account` VALUES (1, '6029621011001', '韩梅梅', 10000);
INSERT INTO `account` VALUES (2, '6029621011000', '李大雷', 10000);
SET FOREIGN_KEY_CHECKS = 1;
@Transactional示例:其它类似
/**
* @Description: @Transactional注解
* @Author: Created by OrangeZh
* @Date: Created in 2020/9/4 17:37
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
String value() default "";
String transactionManager() default "";
}
/**
* 代理对象工厂:生成代理对象的
*/
@Component("proxyFactory")
public class ProxyFactory {
@Autowired
private TransactionManager transactionManager;
/**
* Jdk动态代理
*
* @param obj 委托对象
* @return 代理对象
*/
public Object getJdkProxy(Object obj) {
// 获取代理对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try {
// 开启事务(关闭事务的自动提交)
transactionManager.beginTransaction();
result = method.invoke(obj, args);
// 提交事务
transactionManager.commit();
} catch (Exception e) {
e.printStackTrace();
// 回滚事务
transactionManager.rollback();
// 抛出异常便于上层servlet捕获
throw e;
}
return result;
}
});
}
/**
* 使用cglib动态代理生成代理对象
*
* @param obj 委托对象
* @return
*/
public Object getCglibProxy(Object obj) {
return Enhancer.create(obj.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object result = null;
try {
// 开启事务(关闭事务的自动提交)
transactionManager.beginTransaction();
result = method.invoke(obj, objects);
// 提交事务
transactionManager.commit();
} catch (Exception e) {
e.printStackTrace();
// 回滚事务
transactionManager.rollback();
// 抛出异常便于上层servlet捕获
throw e;
}
return result;
}
});
}
}
/**
* 事务管理器类:负责手动事务的开启、提交、回滚
*/
@Component("transactionManager")
public class TransactionManager {
@Autowired
private ConnectionUtils connectionUtils;
// 开启手动事务控制
public void beginTransaction() throws SQLException {
connectionUtils.getCurrentThreadConn().setAutoCommit(false);
}
// 提交事务
public void commit() throws SQLException {
connectionUtils.getCurrentThreadConn().commit();
}
// 回滚事务
public void rollback() throws SQLException {
connectionUtils.getCurrentThreadConn().rollback();
}
}
/**
* @Description: IOC容器 bean工厂
* @Author: Created by OrangeZh
* @Date: Created in 2020/9/4 15:15
*/
public class BeanFactory {
//外部配置文件配置信息
private static Properties properties = new Properties();
private static final String classpath = BeanFactory.class.getResource("/").getPath();
//bean定义Map 处理存放bean的基本信息
private static Map<String, Class<?>> beanDefinitionMap = new ConcurrentHashMap<>();
//缓存bean 容器缓存(单例缓存池)
private static ConcurrentHashMap<String, Object> beanMap = new ConcurrentHashMap<>();
//扫描到的所有类
private static List<Class<?>> classList = new ArrayList<>();
static {
initIoc();
}
/**
* 初始化容器
* 1、获取配置文件配置内容
* 2、配置类(AppConfig)解析
* 3、扫描包下的所有类
* 4、遍历所有类,并放入到beanDefinitionMap中
* 5、实例化并初始化所有bean
*/
private static void initIoc() {
try {
//1、获取配置文件配置内容
properties = getProperties("jdbc.properties");
//2、配置类解析
Class<?> configClass = AppConfig.class;
String configBeanName = Introspector.decapitalize(configClass.getSimpleName());
beanDefinitionMap.put(configBeanName, configClass);
String[] scanPackages = configClass.getAnnotation(ComponentScan.class).value();
//3、加载包下的所有类
if (scanPackages.length > 0) {
for (String scanPackage : scanPackages) {
getAllClasses(scanPackage, classList);
}
} else {
getAllClasses("", classList);
}
//4、遍历所有类,并放入到beanDefinitionMap中
if (classList.size() > 0) {
for (Class<?> clazz : classList) {
String beanName = Introspector.decapitalize(clazz.getSimpleName());
//类注解
if (clazz.isAnnotationPresent(Component.class)) {
Component annotation = clazz.getAnnotation(Component.class);
if (!annotation.value().equals("")) {
beanName = annotation.value();
} else if (clazz.getInterfaces().length > 0) {
beanName = Introspector.decapitalize(clazz.getInterfaces()[0].getSimpleName());
}
} else if (clazz.isAnnotationPresent(Service.class)) {
Service annotation = clazz.getAnnotation(Service.class);
if (!annotation.value().equals("")) {
beanName = annotation.value();
} else if (clazz.getInterfaces().length > 0) {
beanName = Introspector.decapitalize(clazz.getInterfaces()[0].getSimpleName());
}
} else if (clazz.isAnnotationPresent(Repository.class)) {
Repository annotation = clazz.getAnnotation(Repository.class);
if (!annotation.value().equals("")) {
beanName = annotation.value();
}
} else {
continue;
}
beanDefinitionMap.put(beanName, clazz);
}
}
//5、实例化并初始化所有bean
//先初始化配置类
getBean(configBeanName);
for (String beanName : beanDefinitionMap.keySet()) {
getBean(beanName);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建bean
* 1、实例化Bean
* 2、初始化Bean
*
* @param beanName
* @throws Exception
*/
private static Object doCreateBean(String beanName) throws Exception {
Object bean = beanMap.get(beanName);
if (bean != null) {
return bean;
}
createBeanInstance(beanName);
populateBean(beanName);
return beanMap.get(beanName);
}
/**
* 实例化Bean
*
* @param beanName
* @throws Exception
*/
private static void createBeanInstance(String beanName) throws Exception {
Class<?> clazz = beanDefinitionMap.get(beanName);
//实例化
Object bean = clazz.newInstance();
if (clazz.isAnnotationPresent(Transactional.class)) {
//转为代理对象
ProxyFactory proxyFactory = (ProxyFactory) getBean("proxyFactory");
if (clazz.getInterfaces().length > 0) {
bean = proxyFactory.getJdkProxy(bean);//代理对象替换原对象
} else {
bean = proxyFactory.getCglibProxy(bean);//代理对象替换原对象
}
}
beanMap.put(beanName, bean);
}
/**
* 初始化Bean
* 解析 @Autowired、@Value、@Transactional等注解
*
* @param beanName
*/
private static void populateBean(String beanName) throws Exception {
Object bean = getBean(beanName);
Class<? extends Object> clazz = bean.getClass();
//自动注入
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields) {
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType().equals(Autowired.class)) {
//Autowired autowiredAnno = field.getAnnotation(Autowired.class);
//通过属性名称 获取bean
Object value = getBean(field.getName());
field.setAccessible(true);
//给属性赋值
field.set(bean, value);
} else if (annotation.annotationType().equals(Value.class)) {
Value valueAnno = field.getAnnotation(Value.class);
String value = valueAnno.value();
if (value.startsWith("${") && value.endsWith("}")) {
value = properties.getProperty(value.split("\\$\\{")[1].split("}")[0]);
}
field.setAccessible(true);
//给属性赋值
field.set(bean, value);
}
}
}
//方法注解
Method[] methods = clazz.getMethods();
for (Method method : methods) {
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType().equals(Transactional.class)) {
//转为代理对象
ProxyFactory proxyFactory = (ProxyFactory) getBean("proxyFactory");
Class<?>[] cl = clazz.getInterfaces();
if (clazz.getInterfaces().length > 0) {
bean = proxyFactory.getJdkProxy(bean);//代理对象替换原对象
} else {
bean = proxyFactory.getCglibProxy(bean);//代理对象替换原对象
}
beanMap.put(beanName, bean);
} else if (annotation.annotationType().equals(Bean.class)) {
Bean beanAnno = method.getAnnotation(Bean.class);
Class<?> returnClass = method.getReturnType();
String beanName1 = Introspector.decapitalize(returnClass.getSimpleName());
if (!beanAnno.value().equals("")) {
beanName1 = beanAnno.value();
}
//获取方法执行返回的对象,返回的就是bean
Object beanClass = method.invoke(bean);
beanMap.put(beanName1, beanClass);
}
}
}
}
/**
* 获取bean
*
* @param beanName
* @return
*/
public static Object getBean(String beanName) throws Exception {
Object bean = beanMap.get(beanName);
if (bean == null) {
bean = doCreateBean(beanName);
}
return bean;
}
/**
* 获取某个包下的所有类
*
* @param classes 存放类的list
* @param packageName 包名
* @return
*/
private static void getAllClasses(String packageName, List<Class<?>> classes) {
try {
//将包名转换为路径
String path = classpath + packageName.replaceAll("\\.", Matcher.quoteReplacement(File.separator));
File file = new File(path);
File[] fileList = file.listFiles();
if (null != fileList && fileList.length > 0) {
for (File curFile : fileList) {
if (curFile.isFile()) {
System.out.println("file is:" + curFile);
System.out.println(packageName + "." + curFile.getName().split("\\.")[0]);
Class<?> aClass = Class.forName(packageName + "." + curFile.getName().split("\\.")[0]);
classes.add(aClass);
}
if (curFile.isDirectory()) {
System.out.println("dir is :" + curFile);
getAllClasses(packageName + "." + curFile.getName(), classes);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 读取配置文件
*
* @return
*/
private static Properties getProperties(String... files) {
Properties properties = new Properties();
try {
if (files.length > 0) {
for (String file : files) {
InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream(file);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
properties.load(inputStreamReader);
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Get properties is fail!");
}
return properties;
}
⼯程—>tasks—>compileTestJava
1、进入源码前准备TestBean和测试用例 此次源码分析主要以Bean初始化为主线
public class ItBean {
private TestBean testBean;
public void setLagouBean(TestBean testBean) {
this.testBean = testBean;
}
/**
* 构造函数
*/
public ItBean(){
System.out.println("ItBean 构造器...");
}
}
public class TestBean implements InitializingBean, ApplicationContextAware {
private ItBean itBean;
public void setItBean(ItBean itBean) {
this.itBean = itBean;
}
/**
* 构造函数
*/
public TestBean(){
System.out.println("TestBean 构造器...");
}
}
2、ClasspathXmlApplicationContext 为例,进入源码流程
/**
* ApplicationContext是容器的高级接口,BeanFactory(顶级容器/根容器,规范了/定义了容器的基础行为)
* Spring应用上下文,官方称之为 IoC容器(错误的认识:容器就是map而已;准确来说,map是ioc容器的一个成员,叫做单例池, singletonObjects,容器是一组组件和过程的集合,包括BeanFactory、单例池、BeanPostProcessor等以及之间的协作流程)
*
* Ioc容器创建管理Bean对象的,Spring Bean是有生命周期的
* 构造器执行、初始化方法执行、Bean后置处理器的before/after方法、:AbstractApplicationContext#refresh#finishBeanFactoryInitialization
* Bean工厂后置处理器初始化、方法执行:AbstractApplicationContext#refresh#invokeBeanFactoryPostProcessors
* Bean后置处理器初始化:AbstractApplicationContext#refresh#registerBeanPostProcessors
*/
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
TestBean testBean = applicationContext.getBean(TestBean.class);
3、在TestBean 构造器方法处打断点,看在哪个方法对Bean进行了初始化
由上图可看出调用的方法路径
4、org.springframework.context.support.ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframework.context.ApplicationContext)
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {
super(parent);
setConfigLocations(configLocations);
//是否刷新容器
if (refresh) {
//初始化容器
refresh();
}
}
5、org.springframework.context.support.AbstractApplicationContext#refresh
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 第⼀步:刷新前的预处理
prepareRefresh();
// 第⼆步:获取BeanFactory;默认实现是DefaultListableBeanFactory,加载BeanDefinition 并注册到 BeanDefinitionRegistry
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 第三步:BeanFactory的预准备⼯作(BeanFactory进⾏⼀些设置,⽐如context的类加载器等)
prepareBeanFactory(beanFactory);
try {
// 第四步:BeanFactory准备⼯作完成后进⾏的后置处理⼯作
postProcessBeanFactory(beanFactory);
// 第五步:实例化并调⽤实现了BeanFactoryPostProcessor接⼝的Bean
invokeBeanFactoryPostProcessors(beanFactory);
// 第六步:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执⾏
registerBeanPostProcessors(beanFactory);
// 第七步:初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
initMessageSource();
// 第⼋步:初始化事件派发器
initApplicationEventMulticaster();
// 第九步:⼦类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑
onRefresh();
// 第⼗步:注册应⽤的监听器。就是注册实现了ApplicationListener接⼝的监听器bean
registerListeners();
// 第⼗⼀步:初始化所有的⾮懒加载的单例bean实例(未设置属性)
//填充属性
//初始化⽅法调⽤(⽐如调⽤afterPropertiesSet⽅法、init-method⽅法)
//调⽤BeanPostProcessor(后置处理器)对实例bean进⾏后置处
finishBeanFactoryInitialization(beanFactory);
// 第⼗⼆步:完成context的刷新。主要是调⽤LifecycleProcessor的onRefresh()⽅法,并且发布事件(ContextRefreshedEvent)
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
6、org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization 初始化Bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// 实例化所有剩余(非惰性init)单例
beanFactory.preInstantiateSingletons();
}
7、org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons 实例化所有剩余(非惰性init)单例
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 实例化所有剩余的(非延迟初始化)单例Bean,beanDefinitionNames在创建BeanFactory时就缓存了
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //判断是否是非抽象类,是否是单例,是否是非懒加载
if (isFactoryBean(beanName)) { //判断是否是FactoryBean,是的话要加 & 前缀获取
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else { //获取Bean
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
8、org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String) 从容器中获取Bean 9、org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
getSingleton()方法从单例池获取Bean doGetBean()中先从单例池中获取,如果没有再创建,并放入单例池中,再获取
10、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[]) 创建Bean实例
11、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean 创建Bean实例,填充Bean属性
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 实例化Bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args); //创建Bean实例
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 初始化Bean实例
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper); //填充Bean属性,循环依赖(三级缓存逻辑也就从此处开始)
exposedObject = initializeBean(beanName, exposedObject, mbd); //初始化Bean
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
1、发生在populateBean方法:填充属性,这一步主要是对bean的依赖属性进行注入(@Autowired), 此时会出现A依赖于B,B又依赖于A这种情况;
2、三级缓存:
3、getSingleton方法:
1、编写配置类SpringConfig、AopTestBean和AopTestAspect
/**
* @Description: 配置类
* @Author: Created by OrangeZh
* @Date: Created in 2020/11/25 15:00
*/
@Configuration
@ComponentScan("com.ozdemo")
@EnableAspectJAutoProxy //开启spring对注解AOP的⽀持
public class SpringConfig {
}
/**
* @Description: Aop测试对象
* @Author: Created by OrangeZh
* @Date: Created in 2020/11/25 14:38
*/
@Component
public class AopTestBean {
public void test(){
System.out.println("AopTestBean.test方法执行了");
}
}
/**
* @Description: 切面类
* @Author: Created by OrangeZh
* @Date: Created in 2020/11/25 14:40
*/
@Component
@Aspect
public class AopTestAspect {
@Pointcut("execution(* com.ozdemo.test.AopTestBean.*(..))")
public void pointcut(){
}
@Before("pointcut()")
public void before() {
System.out.println("before method ......");
}
@After("pointcut()")
public void after() {
System.out.println("after method ......");
}
}
2、编写测试用例进入源码
@Test
public void testAOP() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
AopTestBean aopTestBean = applicationContext.getBean(AopTestBean.class);
aopTestBean.test();
}
由上图我们可以看出getBean 之前,AopTestBean 对象已经产⽣(即在第⼀⾏初始化代码中完成),⽽且该对象是⼀个代理对象(Cglib代理对象),我们断定,容器初始化过程中⽬标Ban已经完成了代理,返回了代理对象。
3、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition) 初始化Bean 这一步的源码就接着IOC的11步继续了
/**
*
* 初始化Bean
* 包括Bean后置处理器初始化
* Bean的⼀些初始化方法的执行init-method
* AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
* Bean的实现的声明周期相关接口的属性注入
*/
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 执⾏所有的AwareMethods
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 执⾏所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前的处理器方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 这⾥就开始执行afterPropertiesSet(实现了InitializingBean接口)方法和initMethod
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 整个Bean初始化完成,执⾏后置处理器⽅法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
4、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization 遍历执行后置处理器 5、org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization 创建代理对象的后置处理器
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 检查下该类是否已经暴露过了(可能已经创建了,⽐如A依赖B时,创建A时候,就会先去创建B,当真正需要创建B时,就没必要再代理⼀次已经代理过的对象),避免重复创建
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
6、org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//得到所有候选Advisor,对Advisors和bean的⽅法双层遍历匹配,最终得到⼀个List<Advisor>,即specificInterceptors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
7、org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy 为指定 bean 创建代理对象
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
//创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
//根据⼀些情况判断是否要设置proxyTargetClass=true
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 把指定和通⽤拦截对象合并, 并都适配成Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
8、org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)
public Object getProxy(@Nullable ClassLoader classLoader) {
//创建aop代理对象 提供了两种:jdk proxy, cglib
return createAopProxy().getProxy(classLoader);
}
org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy 创建代理对象,jdk proxy, cglib org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
/**
* 这里决定创建代理对象是用JDK Proxy,还是⽤ Cglib 了,最简单的从使用方面使⽤来说:设置proxyTargetClass=true强制使⽤Cglib 代理,什么参数都不设并且对象类实现了接口则默认用JDK 代 理,如果没有实现接⼝则也必须⽤Cglib
* @param config the AOP configuration in the form of an
* AdvisedSupport object
* @return
* @throws AopConfigException
*/
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
9、org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader) 创建CglibAopProxy,⽣成代理类,并且创建⼀个代理类的实例
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。