JAVA总结-Spring

Spring 是一个轻量级、非入侵式的控制反转 (IoC) 和面向切面 (AOP) 的框架

https://mp.weixin.qq.com/s/GDNLVMJTgLHgF8uIT6jfOQ

一、spring注入方式选择

        1、属性注入

@Service
public class AService {

    @Autowired
    BService bService;
}

        属性注入限制:类只能在IOC容器中使用,对于IOC容器以外的环境,除了使用反射获取依赖之外,无法复用该实现类

        2、SET方法注入

@Service
public class AService {

    BService bService;

    @Autowired
    public void setbService(BService bService) {
        this.bService = bService;
    }
}

        Spring3.0 文档中,官方提倡 set 方法注入,说构造方法注入属性太多可能会让代码变得非常臃肿

        3、构造方法注入

@Service
public class AService {

    BService bService;
    
    @Autowired
    public AService(BService bService) {
        this.bService = bService;
    }
}

        Spring4.x 开始,官方推荐通过构造方法注入的方式,能够保证注入的组件不可变,并且能够确保需要的依赖不为空

        优点: 

        1、依赖不可变:对象创建后无法再通过set方法等改变

         2、依赖不为空:自动检查注入对象不为空才注入成功

         3、完全初始化:获取依赖对象已经初始化了,拿到的对象已经初始化

二、spring容器注入bean方式

        1、@Configuration + @Bean

                1.1、@Configuration声明配置类, @Bean 注解加入容器

                

                

        2、@Componet + @ComponentScan

                2.1、@Componet声明组件类

                

                 2.2、@ComponentScan扫描注入spring容器

     

      

         3、@Import注解导入

         3.1、@Import导入需要注入到容器类

        

        3.2、@Import + ImportSelector:自定义ImportSelector,重写selectImports 方法将注入spring容器的bean全量名

         3.3 @Import + ImportBeanDefinitionRegistrar

         3.4 @Import + DeferredImportSelector

       

         4、使用FactoryBean接口

        5、使用 BeanDefinitionRegistryPostProcessor

 Spring容器启动执行 BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry 方法,通过手动向beanDefinitionRegistry中注册了person的BeanDefinition,将Person对象管理到Spring容器中

        

三、ApplicationRunner、CommandLineRunner、InitializingBean、@PostConstruct 执行顺序

        3.1、CommandLineRunner和ApplicationRunner的作用相同,入参不同        

         3.2、InitializingBean为bean提供了初始化方法的方式,afterPropertiesSet方法

@PostConstruct>InitializingBean>ApplicationRunner>CommandLineRunner

三、springboot运行jar包

        1、springboot提供插件spring-boot-maven-plugin把程序打包成一个可执行jar包:project-name.jar

<build>
   <finalName>project-name</finalName>
   <plugins>
      <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin </artifactId>
      </plugin>        
   </plugins>
</build>       

2、project-name.jar结构

                

         2.1、META-INF程序入口:pom文件、MAINIFEST.MF jar包信息

        Main-Class是org.springframework.boot.loader.JarLauncher,当我们使用java -jar project-name.jar 调用JarLauncher的main方法,而不是我们编写的SpringApplication。

        SpringBoot内部提供SpringBootLoader用于执行SpringApplication工具类

 

         2.2、BOOT-INF:资源文件、依赖包

                        

           2.3、org.springframework.boot.laoder:SpringBootLoader代码

        ​​​​​​​        ​​​​​​​        

                Launcher:基础抽象类:JarLauncher、WarLuncher、PropertiesLauncher

                Archive:归档文件的基础抽象类,

                                JarFileArchive implements Archive:包文件(getUrl、getManifest):内部依赖的jar对应的URL,会使用 !/ 分隔开的协议,SpringBoot 使用org.springframework.boot.loader.jar.Handler处理这些URL

                                ExplodedArchive implements Archive:文件目录的抽象

 

                 JarFile:jar包的封装。JarFileArchive构造方法new JarFile(file)

 

 

3、执行过程

        3.1、JarLauncher构造调用父类ExecutableArchiveLauncher构造方法

               

        3.2、JarLauncher启动入库:构造JarLauncher调用launch方法(参数传递)

        ​​​​​​​        

         3.3、ExecutableArchiveLauncher实现Launcher类执行launch方法

                getClassPathArchives方法在会去找lib目录下对应的依赖JarFileArchive,同时项目自身的JarFileArchive

                LaunchedURLClassLoader类加载器的父类加载器是当前执行类JarLauncher的类加载器

                getMainClass方法会去项目自身的Archive中的Manifest中找出key为Start-Class的类

         

 

 4、MainMethodRunner的run方法

SpringBoot在可执行jar包中定义了自己的一套规则,比如第三方依赖jar包在/lib目录下,jar包的URL路径使用自定义的规则并且这个规则需要使用org.springframework.boot.loader.jar.Handler处理器处理。它的Main-Class使用JarLauncher,如果是war包,使用WarLauncher执行。这些Launcher内部都会另起一个线程启动自定义的SpringApplication类。

这些特性通过spring-boot-maven-plugin插件打包完成。

引用:面试官:为什么SpringBoot的 jar 可以直接运行?

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值