01-Summary

1. methodology

  1. 《设计模式之禅.pdf》
  2. Eureka最纯粹,一通百通。nacos、zool就都明白了
  3. Spring => Spring_MVC => Spring_Boot => Spring_Cloud => Mybatis => Tomcat

1. 基础知识

  1. 设计模式
  2. 数据结构&算法
  3. 反射
  4. 多线程
  5. JVM

2. 注意事项

  1. 不要专注细节
  2. 看注释(接口、类、方法)
  3. 见名知意
  4. 大胆猜测,小心验证
  5. 画图(时序图、结构图、总结图)
  6. 坚持
    1. 技术是死的,根本、本质上都是不变的
    2. 人是活的,所花时间问题而矣
    3. 挤时间、高效率

3. idea_Setting

1. Gradle

image-20230106070339948

2. disorderly_code

image-20230106065420120
-Dfile.encoding=UTF-8
image-20230106065454048

4. offical_doc

image-20221119185419614
image-20221119185525137
image-20221119185543231
image-20221119185247311

2. Spring是什么

  1. Spring => Spring_Boot => Spring_Cloud
  2. Spring => 框架 => 生态 => 拓展性 => 为所欲为
  3. Spring => IOC容器 => 对象bean
    1. IOC(Inversion of Control)控制反转。思想 => DI(Dependency Injection)依赖注入。手段
    2. AOP(Aspect Oriented Programming)面向切面编程

3. Spring使用

容器Map

  1. k: String, v: Object
  2. k: Class, v: Object
  3. k: String, v: ObjectFactory => 三级缓存
  4. k: String, v: BeanDefinition
image-20221107103600575

4. Bean_lifecycle

  1. BeanDefinitionReader接口,加载&解析配置文件
  2. invokeAwareMethods()
  3. invokeInitMethods()
image-20221004093639712
image-20221107110055494

1. singleton

<!-- singleton(默认), prototype, request, session -->
<bean id="ooxx" class="com.listao.Ooxx" scope="prototype"/>

2. 反射

  • 作用:可以获取类,所有属性、方法、构造器、注解

获取Class

  1. Class.forName(完全限定名);
  2. 对象.getClass();
  3. 类名.class();
// 反射,实例化
Constructor ctor = clazz.getConstructor();
Object obj = ctor.newInstance();

3. BeanFactory

  • 整个容器根接口,也是容器入口

The root interface for accessing a Spring bean container.

image-20221017132142101

4. PostProcessor

  • 后置处理器,增强器
    1. BeanFactoryPostProcessor(增强BD)
    2. BeanPostProcessor(增强Bean)
@FunctionalInterface
public interface BeanFactoryPostProcessor {

	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
public interface BeanPostProcessor {

    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

1. PlaceholderConfigurerSupport

  • 在容器创建过程中需要动态的改变bean信息怎么办?
<property name="url" value="${jdbc.url}"/>
image-20230307071005664

2. AbstractAutoProxyCreator

  • AOP核心
image-20230307071309202

postProcessAfterInitialization() => wrapIfNecessary() => createProxy() => proxyFactory.getProxy() => createAopProxy().getProxy()

// 实现类 CglibAopProxy, JdkDynamicAopProxy
public interface AopProxy {

	Object getProxy();
	Object getProxy(@Nullable ClassLoader classLoader);
}

3. MyBFPP

public class T5_BFPP {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("x4_MyBFPP.xml");
        System.out.println("------------------- ac.over -------------------");

        ac.close();
    }
}
<bean class="com.listao.postProcessor.bfpp.MyBFPP"/>
public class MyBFPP implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("MyBFPP.postProcessBeanFactory()");
    }
}

5. Instance

  • 创建对象
    1. 实例化。在Heap中开辟一块空间,对象属性值为默认值
    2. 初始化。给属性设置值
      1. 填充属性
      2. 执行初始化方法init-method

6. Initialize

1. 填充属性

  • populateBean() => setter()

2. Aware

A marker superinterface indicating that a bean is eligible to be notified by the Spring container of a particular framework object through a callback-style method.

  • Aware接口作用?
    • Bean对象需要容器的其他对象,可以实现Aware接口来满足
/**
 * 开发很少用Aware,没必要
 */
public class MyAware implements ApplicationContextAware, EnvironmentAware, BeanNameAware {

    private ApplicationContext applicationContext;
    private Environment environment;
    private String beanName;
}



 





<bean id="myAware" class="com.listao.postProcessor.bpp.MyAware"/>
class T1_Aware {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("x1_2_Aware.xml");
        System.out.println("------------------- ac.over -------------------");

        MyAware a = ac.getBean("myAware", MyAware.class);

        System.out.println("---------------------------------------------");

        System.out.println("a.getApplicationContext() = " + a.getApplicationContext());
        System.out.println("a.getEnvironment() = " + a.getEnvironment());
        System.out.println("a.getBeanName() = " + a.getBeanName());

        ac.close();
    }
}

3. init-method

  • init-method包含属性填充的功能,属性填充更多用setter()
<bean class="ooxx" init-method="ooxx"/>

5. Bean

  1. 普通对象。开发自定义需要的对象
  2. 容器对象。内置对象,Spring需要的对象
    • DefaultListableBeanFactory
    • StandardEnvironment

6. 观察者模式

  • 在不同的阶段要处理不同的工作,应该怎么办?
  • 观察者模式:监听器,监听事件,多播器(广播器),事件源

7. 源码关键接口

  1. BeanFactory
  2. FactoryBean
  3. BeanDefinition
  4. BeanDefinitionReader
  5. BeanFactoryPostProcessor
  6. BeanPostProcessor
  7. Environment => StandardEnviroment
    1. System.getEnv();
    2. System.getProperties();
  8. Aware

1. BF&FB

  • BeanFactory和FactoryBean的区别?
    1. 都是用来创建Obj
    2. BF必须要遵循bean完整的创建过程,这个过程是由Spring来管理控制
    3. FB调用getObject()返回具体Obj,整个Obj的创建是由用户来控制,更加灵活
public class MyFactoryBean implements FactoryBean<Ooxx> {

    @Override
    public Ooxx getObject() throws Exception {
        // 任何创建对象的操作
        return new Ooxx(1, "ooxx");
    }

    @Override
    public Class<?> getObjectType() {
        return Ooxx.class;
    }

    /**
     * 1. true:ooxx为单例,Spring管理,factoryBeanObjectCache缓存
     * 2. false:ooxx不为单例,每次getObject()
     */
    @Override
    public boolean isSingleton() {
        return true;
    }
}



 





 








 



<bean id="myFactoryBean" class="com.listao.myFactoryBean.MyFactoryBean"/>
public class T9_MyFactoryBean {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("x9_myFactoryBean.xml");
        System.out.println("------------------- ac.over -------------------");

        MyFactoryBean byClass = ac.getBean(MyFactoryBean.class);
        System.out.println("byType = " + byClass);

        // 地址符。`transformedBeanName(name)`将(&myFactoryBean => myFactoryBean)
        MyFactoryBean myFactoryBean = ac.getBean("&myFactoryBean", MyFactoryBean.class);
        System.out.println("&myFactoryBean = " + myFactoryBean);

        /*
         * debug
         * isSingleton()可以设置Ooxx是否为singleton
         */
        Ooxx ooxx = ac.getBean("myFactoryBean", Ooxx.class);
        System.out.println("ooxx = " + ooxx.hashCode());

        Ooxx ooxx2 = ac.getBean("myFactoryBean", Ooxx.class);
        System.out.println("ooxx2 = " + ooxx2.hashCode());

        ac.close();
    }
}





 



 















byType = com.listao.myFactoryBean.MyFactoryBean@367ffa75
&myFactoryBean = com.listao.myFactoryBean.MyFactoryBean@367ffa75
ooxx = 1229161065
ooxx2 = 1229161065