2025年java spring菜鸟教程(java spring 教程)

java spring菜鸟教程(java spring 教程)svg xmlns http www w3 org 2000 svg style display none svg

大家好,我是讯享网,很高兴认识大家。



 <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg> 

讯享网

@Configuration

之前使用bean.xml配置spring相关配置读取配置的时候

讯享网

使用注解的时候我们使用配置类来配置spring的相关配置,读取配置如下

 

配置类中我们配置对应的@Bean注解来把对应的类放到容器中,这样我们就可以通过对应的名称来获取容器中的对象了。

讯享网

@ComponentScan

这是一个扫描包的注解,配置对应的value属性可以扫描指定包下的所有类,然后把使用了对应注解的类添加到容器中。

 

其中过滤器有多种属性

讯享网

使用自定义的过滤器,返回true证明扫到的类可用,false表示不可用

 

@Scope注解

讯享网

@Lazy

 

@Conditional

讯享网

对应的WindowsCondition.class,linxu差不多

 

@import

用来向容器中导入类的注解有以下的三种使用方法:

讯享网

第一种使用方法:直接import 类的class对象

 

第二种使用方法:使用importselect来导入

讯享网
 

第三种:使用使用ImportBeanDefinitionRegistrar

讯享网
 

第四种注入bean方法

配置

使用FactoryBean进行容器的注入

1)、默认获取到的是工厂bean调用getObject创建的对象

2)、要获取工程bean本身,我们需要使在默认名称之前加上&,这个是默认的规定

讯享网

ColorFactoryBean类

 

之后我们可以看到容器中有了一个叫做colorFactoryBean的对象。我们获取这个对象可以看到这个对象的属性是class com.atguigu.bean.Color

Bean的生命周期

讯享网
1)、使用@Bean的注解
 
讯享网
2)、继承接口
 
讯享网
3)、JSR250注解
 
4)、初始化的前后通知

把继承的类当做组件添加到容器后生效。会在执行实例的初始化方法前后执行对应的操作

讯享网
一些源码
 

Spring底层对BeanPostProcess的使用

一堆后置处理器,可以完成很多功能的实现

@Value

可以自动配置属性的值,有三种不同的值配置方式

  • 使用基本数值,字符串,int之类的
  • 写SpEL表达式:#{}里面可以进行一些简单的运算操作
  • 使用\({}&#xff0c;从环境中获取对应的数据</li></ul> <pre></pre> <p>其中使用\){}的时候需要注意,需要先把对应的配置文件导入才可以进行自动配置。在xml文件中导入的办法

    讯享网

    在配置文件中导入的方法需要使用@PropertiesSource 来实现,他是一个可以重复使用的注解,可以配置多个

     
    讯享网

    @PropertiesSource

    如上所示,用来获取配置文件的一个注解

    当我们把配置放到了环境中。可以通过注解获取到也可以通过环境来获取到对应的注解属性

     

    @Autowired

    讯享网

    以下为个人理解

    使用@Autowired自动注入的时候,会先去容器中按照类型获取对应的类,来注入到对应的位置。

    image-20210412183847870.png
    讯享网

    但是如果存在多个相同类型的bean那么就会根据一定的规则来选择bean

    image-20210412184245680.png

    如果我们想要自己控制注入的类型的id使用@Qualifier来完成,

    image-20210412184406389.png

    使用@Primary可以告诉容器这个bean是优先级比较高的一个。优先使用带有@Primary的。使用之后也可以使用@Qualifier,但是@Qualifier优先级比@Primary高

    @Autowired可以标注的位置

    image-20210412194739177.png

    • 标注在方法位置:
      • 可以标注在普通类的普通方法上,这样如果方法有参数,参数在容器中存在就会自动注入
      • 普遍使用是和@Bean使用,被bean注解的方法,如果有参数,会自动从容器中寻找对应的方法,而且不用写@Autowired注解
    • 标注在构造方法上:
      • 如果组件只有一个构造方法,那么这个有参构造方法可以不写@Autowired会自动从容器中获取。
      • 如果有多个的话,和普通方法一样,会自动从容器中找到对应的类型注入
    • 放在参数位置上
      • 字面意思。无需多言

    @Resource和其他的自动注入类

     

    在bean中获取底层组件

    讯享网

    Aware.png

     

    @Profile

    spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能

    开发环境,测试环境,生产环境

    数据源:(/A)(/B)(/C);

    讯享网
    示例一:使用虚拟机配置启动环境
     

    image-20210412213542304.png

    启动之后发现只有对应的环境下的数据源可以被获取到

    示例二:配置激活环境
    讯享网

    使用

     

    原理

    AOP原理:@EnableAspectJAutoProxy入手

    流程:

    1、创建IOC容器

    2、注册配置类,然后调用refresh方法。刷新容器

    image-20210414162716019.png

    3、refresh刷新,注册的bean的后置处理器来拦截bean创建:

    image-20210414162759975.png

    3.1先获取IOC容器已经定义的需要创建对象的所有BeanPost

    1.@EnableAspectJAutoProxy

    • @EnableAspectJAutoProxy 通过@Import(AspectJAutoProxyRegistrar.class)给spring容器中导入了一个AnnotationAwareAspectJAutoProxyCreator。
    • AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor,InstantiationAwareBeanPostProcessor是一个BeanPostProcessor。它可以拦截spring的Bean初始化(Initialization)前后和实例化(Initialization)前后。
    1. AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation(bean实例化前):会通过调用isInfrastructureClass(beanClass)来判断 被拦截的类是否是基础类型的Advice、PointCut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect),若是则放入adviseBean集合。这里主要是用来处理我们的切面类。
    2. AnnotationAwareAspectJAutoProxyCreator的BeanPostProcessorsAfterInitialization(bean初始化后):
      1. 首先找到被拦截的Bean的匹配的增强器(通知方法),这里有切入点表达式匹配的逻辑
      2. 将增强器保存到proxyFactory中,
      3. 根据被拦截的Bean是否实现了接口,spring自动决定使用JdkDynamicAopProxy还是ObjenesisCglibAopProxy
      4. 最后返回被拦截的Bean的代理对象,注册到spring容器中
    3. 代理Bean的目标方法执行过程:CglibAopProxy.intercept();
      1. 保存所有的增强器,并处理转换为一个拦截器链
      2. 如果没有拦截器链,就直接执行目标方法
      3. 如果有拦截器链,就将目标方法,拦截器链等信息传入并创建CglibMethodInvocation对象,并调用proceed()方法获取返回值。proceed方法内部会依次执行拦截器链。

    1、使用

    1.导入相关依赖

    数据源,数据库驱动,spring-jdbc模块

    2.配置数据源。。JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据

    3.给方法上标注@Transactional表示当前方法是一个事务方法

    4.@EnableTransactionManagement开启基于注解的事务管理功能

    5.配置事务管理器来控制事务

    讯享网
     
    讯享网
     

    2、原理

    @EnableTransactionManagement上有一个注解会给容器导入一个TransactionManagementConfigurationSelector对象,来进行一些组件的导入

    讯享网

    TransactionManagementConfigurationSelector源码如下:

     

    实导入两个组件

    AutoProxyRegistrar.class

    ProxyTransactionManagementConfiguration.class

    AutoProxyRegistrar干什么的

    继承了注册bean的接口,给容器中注册了一个InfrastructureAdvisorAutoProxyCreator

    InfrastructureAdvisorAutoProxyCreator是做什么的:
    利用后置处理器机制在对象创建一后,包装对象,返回一个代理器对象,代理对象执行方法利用拦截器执行对象。

    ProxyTransactionManagementConfiguratio干什么的

    给容器中利用bean注册各种组件:

    • 事务增强器:
      • 事务注解器:要用事务注解的信息AnnotationTransactionAttributeSour接卸事务的注解
      • 事务拦截器:TransactionInterceptor保存了事务属性信息,事务管理器。他是一个MethodInterceptor方法拦截器。在目标方法执行的时候执行拦截器链。

        讯享网<ul><li>事务拦截器功能 <ul><li>先获取事务属性&#xff0c;再去获取PlatformTransactionManager</li><li>如果出现异常获取事务&#xff0c;回滚&#xff0c;没有异常获取事务提交</li></ul> </li></ul> </li></ul> </li></ul> 

        image-20210415155724554.png

        1.BeanFactoryPostProcessor

        • BeanPostProcessor是Bean后置处理器:bean创建初始化前后进行拦截工作
        • BeanFactoryPostProcessor是Bean工厂后置处理器:
          • 在BeaanFactory标准初始化之后进行调用:所有bean定义已经保存加载到beanFactory,但是Bean的实例还没有创建

        1)、IOC容器创建对象

        2)、invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessors

        • 如何找到所有的BeanFactoryPostProcessor并执行它们的方法
          • 1)、直接在BeanFactory中找到所有类型是BeanFactoryPostProcess的组件,并执行它们的方法。
          • 2)、在初始化其他组件前面执行。

        2.BeanDefinitionRegistryPostProcessor

         

        执行方法:postProcessBeanDefinitionRegistry

        在所有Bean定义信息将要被加载,bean实例还没有被创建的时候。

        这里类的执行顺序比BeanFactoryPostProcessor执行的早,并且可以在这个类中注册bean信息。给容器中添加一些组件。

        原理:

        • 1、IOC创建对象
        • 2、调用刷新方法()-》invokeBeanFactoryPostProcessors(beanFactory);
        • 3、先从容器中获取到所有的BeanDefinitionRegistrayPostProcessor组件。
          • 依次除法所有的postProcessBeanDefinitionRegistry()方法
          • 之后再触发postProcessBeanFactory()方法BeanFactoryPostProcessor;
        • 4、再来从容器中找到BeanFactoryPostProcessor组件,依次除法postProcessBeanFactory()方法。

        ApplicationListener:监听容器中发布的事件。事件驱动模型的开发

        讯享网

        ContextRefreshedEvent:容器刷新事件

        ContextClosedEvent:容器死掉事件

        步骤:

        1、写一个事件监听器来监听某个事件(ApplicationEvent及其子类)

        2、把监听器加入到容器中

        3、只要容器中有相关事件的发布,我们就能监听到这个事件爱你:

         

        4、发布一个事件:

        讯享网

        1)、ContextRefreshedEvent事件;

        • 1、容器创建对象的时候会调用refresh方法
        • 2、finishRefresh()最后的刷新,调用了一个publicEvent(new ContextRefresh())方法
          • 【事件发布流程】

            <ul><li>1.获取到事件的多播器&#xff08;派发器&#xff09;getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);</li><li>multicastEvent:事件派发。</li><li>获取到所有的ApplicationListener <ul><li>for (ApplicationListener&lt;?&gt; listener : getApplicationListeners(event, type))</li><li>如果有Executor可以支持使用Executor进行异步派发。</li><li>否则同步的方式直接执行listener方法。拿到listener回掉onApplicationEvent方法&#xff1b;</li></ul> </li></ul> </li></ul> </li><li>3、容器关闭也会添加一个容器关闭事件。</li></ul> 

            【事件多播器】(事件派发器)

            1、容器创建对象。refresh();

            2、initApplicationEventMulticaster();ApplicationEventMulticaster;

            • 先去容器中找有没有id="applicatinEventMulticaster"的组件
            • 如果没有程序就用自己新建的simpleapplictionEventMulticaster,并加入到容器中,我们就可以在其他组件派发事件的时候自动注入applicationEventMulticaster

            【容器中有哪些监听器】

            1)、容器创建对象:refresh();

            1. .registerListeners();

              从容器中拿到所有的监听器,把他们注册到applicationEventMulticaster中:

              string[] listenerBeanNlmes = getBeanNamesForType(ApplicationListener.class,true, false)

              //将listener注册到ApplicationEventMulticaster中

              getApplicationEventMulticaster( ) . addApplicationListenerBean(listenerBeanName);

            注解开发
            讯享网

            使用@EventListener来进行注解开发

            原理:

             
            SmartInitializingSingleton
            • 1.ioc容器创建对象并refresh()
            • 2.finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例bean;
              • 先创建所有的单实例bean;getBean();
              • 获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的
                • 如果是就调用afterSingletonsInstantiated()

            3.Sping容器创建过程

            Spring容器的创建和刷新refrsh()[创建刷新]

            1、prepareRefresh();预处理工作

            • 1、initPropertySources()初始化一些属性设置。留给子类来做事情的。子类自定义个性化的属性设置方法
            • 2、getEnvironment().validateRequiredProperties();进行属性校验,校验属性和发等等
            • 3、earlyApplicationEvents = new LinkedHashSet<>(); 保存容器中的一些早期的事件

            2、obtainFreshBeanFactory();获取beanfactory;

            • 1、refreshBeanFactory()刷新工厂
              • 创建了一个this.beanFactory = new DefaultListableBeanFactory();
              • 设置id
            • 2、getBeanFactory()返回了工厂;
            • 3、将beanfactory返回DefaultListableBeanFactory

            3、prepareBeanFactory(beanFactory):BeanFactory的预准备工作(BeanFactory进行一些设置)

            • 1、设置Beanfactory的类加载器、支持表达式解析器。
            • 2、添加部分BeanPostProcessor[ApplicaitonContextAwareProcessor]
            • 3、配置忽略的自动装配的接口EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware
            • 4、registerResolvableDependency注册可以解析的自动装配。我们能直接在任何组建中自动装配的部分
            • 5、beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));添加许多的后置处理器
            • 6、添加编译时的Aspect支持;
            • 7、非beanFactory中注册一些能用的组件
              • environment[ConfigurableEnvironment]
              • systemProperties

            4、postProcessBeanFactory(beanFactory);BeanFactory准备工作

            讯享网

            =BeanFactory以及预准备工作===========

            5、invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessors

            • BeanFactoryPostProcessors:BeanFactory的后置处理器,在BeanFactory标准初始化之后执行的
            • 两个接口:BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor
              • 执行BeanFactoryPostProcessor方法
                • 1、获取所有的BeanDefinitionRegistryPostProcessor;
                • 2、看优先级排序PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor/postProcessor.postProcessBeanDefinitionRegistry(registry)
                • 3、在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor
                  • postProcessor.postProcessBeanDefinitionRegistry(registry)
                • 4、最后执行没有实现任何优先级或者是顺序接口的
                  • BeanDefinitionRegistryPostProcessors;postProcessor.postProcessBeanDefinitionRegistry(registry)
                • 再执行BeanFactoryPostProcessor方法
                • 1、获取所有的BeanFactoryPostProcessor
                • 之后方法大致和上面相同

            6、registerBeanPostProcessors(beanFactory);执行BeanPostProcessors,Bean的后置处理器【拦截bean创建过程】

            不同类型的BeanPostProcessor:在Bean创建前后的执行时机是不一样的

            BeanPostProcessor:

            DestructionAwareBeanPostProcessor:

            InstantiationAwareBeanPostProcessor:

            SmartInstantiationAwareBeanPostProcessor:

            MergedBeanDefinitionPostProcessor:【internalPostProcessors】

            • 1、String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);获取所有的beanPostProcessor;后置处理器都默认可以有优先级
            • 2、先注册PriorityOrered优先级接口的BeanPostProcessor
              • 把每一个BeanPostProcessor添加到BeanFactory中
            • 3、再来注册Ordered接口的
            • 4、最后注册的没有实现任何优先级接口的
            • 5、最终注册MergedBeanDefinitionPostProcessor
            • 6、注册一个ApplicationListenerDatector:来在Bean创建完成后检查是否ApplicationListener,如果是
              • applicationcontext.addApplicationListener((ApplicationListener<?>) bean);

            7、initMessageSource();初始化MessageSource组件(做国际化功能消息绑定。消息解析)

            • 1、获取BeanFactory
            • 2、容器中是否为id为messagesource组件,没有就整一个默认的messagesource
              • 如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource:
                • MessageSource:取出估计花配置文件中的某个key的值。
            • 3、把创建好的MessageSource注册在容器中,以后获取国际化标准配置文件的值得时候,可以自动驻入MessageSource;
              • beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME,this.messageSource);
              • MessageSource.getMessage(String code,Object[] args,String defaultMessage,Local…)

            8、initApplicationEventMulticaster();初始化事件派发器

            • 1、获取BeanFactory
            • 2、从BeanFactory中获取ApplicationEventMulticaster的
            • 3、没有配置就自动创建SimpleApplicationEventMulticaster
            • 4、将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接注入

            9、onRefresh();初始化剩下的bean,留给子类的

            • 1、子类重写这个方法。在容器刷新的时候自定义做其他的事情。

            10、registerListeners();

            • 1、从容器中拿到所有的ApplicationListener组件
            • 2、将每个监听器添加到事件派发器中
              • getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
            • 3、派发之前步骤产生的事件。

            11、finishBeanFactoryInitialization(beanFactory);初始化所有单实例的bean

            • 1、beanFactory.preInstantiateSingletons();初始化所有单实例的bean
              • 1、获取容器中的所有bean,依次进行初始化和创建对象。
              • 2、获取bean定义信息RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
              • 3、如果!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()
                • 判断是否是isFactoryBean(beanName);是否实现了FactoryBean
                • 如果不是工厂getBean(beanName);
                  • 1、getBean(beanName);ioc.getBean()
                  • 2、doGetBean(name,null,null,false)
                  • 3、先获取缓存中保存的单实例bean.如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)
                    • 从private final Map<String,object> singleton0bjects
                  • 4、缓存中获取不到,开始Bean的创建流程
                  • 5、标记当前bean已经创建
                  • 6、获取当前Bean依赖的其他bean
                  • 7、启动单实例bean的创建流程
                    • 1、createBean(beanName,mbd,args);
                    • 2、Object bean = resolveBeforeInstantiatino(beanName,mbdToUse);让beanpost提前拦截返回代理对象;
                      • InstantiationAwareBeanPostProcessor:提前执行;
                      • 先触发:postProcessBeforeInstantiation()
                      • 如果有返回值:触发postProcessAfterInitialization
                    • 3、如果前面的InstantiationAwareBeanPostProcessor没有返回代理对象
                    • 4、doCreateBean()创建一个bean实例
                      • 1、创建bean实例CreateBeanInstance
                        • 解析bean类型。利用工厂方法,或者对象构造器,创建出bean实例。
                      • 2、applyMergedBeanDefinitionPostProcessors(mbd, beanType,beanName);
                        • 调用MergedBeanDefinitionPostProcessor bdp.postProcessMergedBeanDefinition(mbd, beanType,beanName) ;
                      • 3、【Bean属性赋值populateBean(beanName,mbd, instancewrapper);
                        • 1、赋值之前判断到InstantiationAwareBeanPostProcessor后置处理器;执行postProcessAfterInstantiation方法
                        • 2、拿到InstantiationAwareBeanPostProcessor后置处理器
                          • postProcessPropertyProcessor
                        • 赋值之前:==========
                        • 3、applyPropertyvalues( beanName,mbd,bw, pvs) ;应用bean属性的值。
                      • 4、【bean】初始化initializeBean( beanName, exposedobject, mbd);
                        • 1、invokeAwareMethods(beanName, bean);执行Aware接口的方法
                          • BeanNameAwareBeanclaswareBeanFactorvAwarer
                        • 2、【执行】applyBeanPostProcessorsBeforeInitialization
                          • BeanPostProcessor.postProcessBeforeInitialization
                        • 3、执行初始化方法invokeInitMethods(beanName,wrappedBean,mbd);
                          • 1、是否是InitializingBean接口的实现;
                          • 2、是否自定义初始化方法;
                        • 4、【执行后置处理器初始化之后】applyBeanPostProcessorsAfterInitialization
                          • BeanPostProcessor.postProcessAfterInitialization()
                        • 5、注册Bean的销毁方法;
                      • 5、将创建的Bean添加到缓存中singletonObjects;
                        • ioc容器就是这些Map;很多的Map里面保存了单实例Bean,环境信息。。。。
              • 所有Bean都利用getBean创建完成以后;
                • 检查所有的Bean是否是SmartInitializingSingleton接口的,如果是,就执行afterSingletonsInstant
            • 12、finishRefresh()完成初始化创建工作。IOC容器创建完成
                1. 、initLifecycleProcessor();初始化和生命周期有关的后置处理器;LifecycleProcessor
                  写一个LifecycleProcessor的实现类,可以在BeanFactory
                  void onRefresh();
                  void onclose();
              • 2)、getLifecycleProcessor( ).onRefreshO;
                • 拿到前面定义的生命周期处理器(BeanFactory)﹔回调
                1. . publishEvent(new ContextRefreshedEvent(this));发布
              • 4)、veBeansview.registerApplicationcontext(this);

            总结

            1、spring容器在启动的时候会保存所有注册进来的Bean定义信息

             

            2、Spring容器在合适的时机创建这些bean

            讯享网

            3、后置处理器:

             

            4、事件驱动模型:

            讯享网

            在这里插入图片描述

            1. 用户发送请求至前端控制器。
            2. 前端控制器收到请求调用处理器映射器。
            3. 处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器,一并返回给前端控制器。
            4. 前端控制器调用处理器适配器,处理器适配器经过适配调用具体的处理器(controller,也叫后端控制器)。
            5. controller 执行完成返回 ModelAndView。
            6. 处理器适配器将 controller 执行结果 ModelAndView 返回给 前端控制器。
            7. 前端控制器将 ModelAndView 传给 视图解析器。
            8. 视图解析器解析后返回 VIew。
            9. 前端控制器根据 View 进行渲染视图(将模型数据填充至页面)。
            10. 前端控制器响应给用户。

            ● 原理:利用预编译的机制将sql语句的主干和参数分别传输给数据库。
            ● JDBC中使用PreparedStatement可以防止sql注入。
            ● mybatis中提供了两种方式:#{} 和 \({}、<br /> ● #{}: 在预处理时&#xff0c;会把参数部分作为一个占位符 ? 代替。能有效解决sql注入问题。<br /> ● \){}: 表示拼接字符串,并将接受的内容不加修饰符拼接到sql中,将会引起sql注入问题。

小讯
上一篇 2025-05-16 21:55
下一篇 2025-04-24 10:51

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/203494.html