spring源码理解

百度网盘--spring书籍

1. spring创建Bean

如下配置:Spring是将接口UserMapper交给MapperFactoryBean, 实现里面的方法,产生一个代理对象,这样,代码中就可以使用@Autowired进行注入使用;

//依赖xml, 单个mapper
<bean id = "userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"
    <property name="mappInterface" ref="org.mybatis.spring.sample.UserMapper" />
    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

 探究Spring是如何产生动态代理的?

package com.feng.mapper;

import com.feng.dto.UserDTO;
import org.apache.ibatis.annotations.Insert;

public interface UserMapper {

    @Insert("select * from tab_user")
    public void selectUser(UserDTO userDTO);

}

Spring 创建的动态代理类UserMapper是如何注入Spring容器中的?

@Service
public class UserService {

    /**
     * userMapper:Object
     * 动态代理
     */
    @Autowired
    private UserMapper userMapper;

    public void save(Map<String, Object> map){
        
        UserDTO userDTO = new UserDTO();
        userDTO.setId("111");
        userDTO.setUsername("zhangsan");

        userMapper.selectUser(userDTO);
    }

}

而我们自己代理产生的对象不在容器中,没办法注入

Class[] clazz = new Class[]{ UserMapper.class };
UserMapper userMapper = (UserMapper)Proxy.newProxyInstance(
                                        this.getClass().getClassLoader(), 
                                        clazz, 
                                        new UserMapperHandler());


解决问题?
如何把一个代理对象放入Spring容器中?

Spring是如何放容器的?

Spring实例化bean 读取类上的注解信息,比如@Compent

spring先解析xml文件或者注解配置,读取所有要加载类信息。根据类信息创建对应的BeanDefinition对象,再根据Beandefination对象创建实例对象。

一个普通类包含如下属性信息:

  • name
  • scope
  • 构造方法
  • 注入模型(byName or byType)
  • lazy
  • static

将类上的信息放入BD中(BeanDefinition),如果有多个类就创建多个BD ,然后将DB放入BeanDefinitionMap中;

BeanDefinition是SpringBean的描述对象,主要封装了如下信息:

此时,如果程序员提供了一个类实现接口: BeanFactotyPostProcessor

@FunctionalInterface
public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

spring 将先处理实现类中的逻辑(可以拿到Map,进而修改了beanClass)
然后Spring调用方法 preInstantiateSingletons, 根据BD中类的信息, 将bean给new出来;

package org.springframework.beans.factory.config;

import java.util.Iterator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.lang.Nullable;

public interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {

    void registerResolvableDependency(Class<?> var1, @Nullable Object var2);

    boolean isAutowireCandidate(String var1, DependencyDescriptor var2) throws NoSuchBeanDefinitionException;

    BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException;

    Iterator<String> getBeanNamesIterator();

    //
    void preInstantiateSingletons() throws BeansException;
}

        如果想要把代理对象放入容器中,就新生成一个BeanDefinition, 然后将BD放入Spring容器中,但是BeanFactotyPostProcessor 只提供了update方法,而没有提供add方法

        如何放入?

        Spring提供类一个接口:ImportBeanDefinitionRegistrar,可以注册BeanDefinition

public interface ImportBeanDefinitionRegistrar {

    default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {

        BeanDefinitionBuilder bdBuilder =  BeanDefinition.genericBeanDefinition(UserFactoryBean.class);
        AbstractBeanDefinition beanDefinition = bdBuilder.getBeanDefinition();
    
        beanDefinition.getConstructorArgumentValues()
                      .addGenericArgumentValue("com.feng.mapper.UserMapper");
    
        registry.registerBeanDefinition("UserFactoryBean", beanDefinition);
    }

    default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    }
}


        FactoryBean 是一个bean,而且是一个特殊的bean,它实现了接口(依赖)

@Import(ImportBeanDefinitionRegistrar.class)

小结:Spring实例化一个Bean中,重要的三个接口:

  • BeanFactotyPostProcessor
  • ImportBeanDefinitionRegistrar
  • FactoryBean

下面是普通类实例化的流程图:

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

time Friend

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值