文章目录
- 前言
 - 一、jar包中,相同class不同类加载器加载的时候是同一个class嘛?
 - 二、利用ConfigurableListableBeanFactory手动注册bean
 - 注册bean,并自动注入依赖bean
 - 根据类型获取注入的bean,两个bean是一个吗?
 
- 三、同一份字节码,class隔离,bean隔离
 - 总结
 
前言
注入一个bean常用的方式有几种: 加注解,spring.favorite中添加类全路径 等
今天涉及到了一个问题,就是需要在程序中,根据名字,在jar中寻找class,动态加载对象,然后变成bean 注入到spring容器中,当然还有其他问题;
一、jar包中,相同class不同类加载器加载的时候是同一个class嘛?
做如下验证,同一个jar包,通过两个类加载器加载,看是否为同一个class,整体代码如下: 
 测试类;
@SpringBootTest
public class ClassLoadTest {
    @Autowired
    ApplicationContext context;
    @Test
    void ss() throws Exception {
        
        String path = "D:\\Java-develop\\project\\token\\src\\main\\resources\\jar\\platform-base-system-3d-public-1.0-SNAPSHOT-plain.jar";
        URL[] urls = {new URL("file:" + path)};
        URLClassLoader urlClassLoader = new URLClassLoader(urls);
        URLClassLoader urlClassLoader1 = new URLClassLoader(urls);
        Class<?> aClass = urlClassLoader.loadClass("com.platform.base.system.system.util.StringUtils");
        Class<?> aClass1 = urlClassLoader1.loadClass("com.platform.base.system.system.util.StringUtils");
        SpringUtil.registerBean("javaInfo", aClass.newInstance());
        SpringUtil.registerBean("javaInfo1", aClass1.newInstance());
        Object javaInfo = context.getBean(aClass);
        System.out.println(javaInfo);
        Object javaInfo1 = context.getBean(aClass1);
        System.out.println(javaInfo1);
        Object bean = context.getBean("javaInfo");
        System.out.println(bean);
        System.out.println(context.getBean("javaInfo").equals(context.getBean("javaInfo1")));
    }
}
 
debug可以看到:
 
 不同的类加载器,加载同一个jar的同一个class,加载到的class也是不一样的; 分别为8554 / 8555
二、利用ConfigurableListableBeanFactory手动注册bean
注册bean,并自动注入依赖bean
  SpringUtil.registerBean("javaInfo", aClass.newInstance());
  SpringUtil.registerBean("javaInfo1", aClass1.newInstance());
 
- 由于注入的bean名称不能一直,所以这里设置不同的bean名称
 - 然后将每个class初始化后,注入到spring容器中
 
根据类型获取注入的bean,两个bean是一个吗?
Object javaInfo = context.getBean(aClass);
System.out.println(javaInfo);
Object javaInfo1 = context.getBean(aClass1);
System.out.println(javaInfo1);
 
可以看到:
 
 这是不同的两个bean,分别为: 8547 / 8556
三、同一份字节码,class隔离,bean隔离
为什么 同一份字节码,class隔离,bean隔离?
 
- 虽然是同一份字节码,但是由于是不同的类加载器加载的,所以造成了class隔离
 - 由于是不同的class,所以后续注入bean的时候,也造成了bean隔离
 
这样的意义在于:
 当不同jar中,存在相同bean的时候,即使完全一样的class,在通过类加载器加载的时候,也不会造成问题
总结
- 加载jar包中的class
 - 根据加载的class创建对象
 - 手动创建bean,注入spring容器中
 - 每个类加载器不同,那么加载的class也一定不同
 


















![CPP-SCNUOJ-Problem P24. [算法课贪心] 跳跃游戏](https://img-blog.csdnimg.cn/direct/0cbfd74c75b641c1acbdd337f613d27d.png)
