spring boot @value取不到值_Spring和Spring Boot相关知识整理

1、 思维导图

15ca6ac4029c4e74844e9c404f4b53ef

2、 Spring

(1)AOP术语

  1. 通知Advice ——切面要做什么,何时执行。何时,包括方法调用前、方法调用后、方法成功调用后、方法调用抛异常后、环绕(Around)。环绕允许提供一些需要跨越方法调用前后的功能,如计算调用耗时。
  2. 连接点Joinpoint —— 应用执行时能插入切面的点。实际上是一个逻辑概念,不体现在配置中。
  3. 切点Pointcut —— 执行通知的具体的连接点。
  4. 切面Aspect —— 通知+切点
  5. 引入Introduction ——允许为类添加新的方法或属性。(个人理解即应用使用切面中的方法和属性,就好像这些方法和属性是原生的一样。可以参考aop:declare-parents元素)
  6. 织入Weaving —— 将切面应用到目标对象创建新的代理对象的过程,Spring使用的是运行时。编译期和类加载时是其他的方式。

(2) Bean的生命周期
虽然被称为生命周期,实际上指的是bean在初始化、回收期间调用了哪些方法。如果只看《Spring实战》,可以看到类似下面的图

87d0bbe45dec4704bd1720c8efee41f7

(3) Cglib和JdkProxy

1、与Spring的关系

这是Spring AOP的两种实现方式。根据官方文档:

  • 默认使用JdkProxy
  • 对于被代理对象没有实现任何接口,使用Cglib
  • 可以强制指定使用Cglib。这样就可以解释为什么有的bean实现了接口,有的没有,但是在同一个工程中可以并存了

2、示例代码

23e362ee-8395-4d08-968d-0dec9f506cdd
2c1492f14403478db929d67d459d8f1d
69c86c39501a4eb3883f807d34ed1437
ae9ee24503a44833a7239e26fb8c09e3

3、比较
比较一下两者的区别,这也是常见的面试问题。

JdkProxyCglib依赖被代理对象实现了接口(所有接口的方法数总和必须>0[4])引入asm、cglib jar ;不能是final类和方法原理反射,实现被代理对象接口的匿名内部类,通过InvocationHandler.invoke()包围被代理对象的方法引入asm、cglib jar,代理类实现MethodInterceptor,通过底层重写字节码来实现效率创建快,运行慢(见下方说明2)创建慢,运行快

说明: Cglib是如何修改字节码,从代码上是看不出来的。使用的是ASM技术,修改class文件,可以自行查阅。 JDK1.8及以后,JdkProxy的运行速度已经比Cglib快了(之前则是慢于Cglib)。

4、关于org.apoalliance.intercept.MethodInterceptor

787ae040a9fe4983891d02b1c7f695ba

声明代理链

a2a32c9a2eeb43b19db038ff1244ab33

4) 构造方法注入和设值注入的区别

注:设值注入指的是通过setter注入。

换一种说法:

  1. 如果只设置基本类型(int、long等)的值,建议设置默认值而不是通过任何一种注入完成
  2. 构造注入不支持大部分的依赖注入。构造注入仅在创建时执行,设值注入的值在后续也可以变化。
  3. 设值注入可以支持尚未完整的被依赖的对象,构造注入则不行。可以通过构造注入决定依赖关系,因此如果依赖关系不会发生变更也可以选择依赖注入。

(5)ApplicationContext事件

可以通过实现ApplicationEvent类和ApplicationListener接口,进行ApplicationContext的事件处理。这是标准的发送者-监听者的模型,可以用来处理业务逻辑,将代码解耦。
但是,发送和接收实际上是同步的,如果有事务,会在同一个事务内,并不能作为异步处理机制。

3. SpringBoot

(1)SpringBoot的关键注解

所谓核心注解,这里指的是相对Spring本身新增的一些注解,来看看它们有什么作用。
恰好这里提到的注解,都可以打在SpringBoot的启动类(不限于启动类),用下面的代码片段来进行说明。代码示例:

b5724df515a74ee59a45bf82f3cb1053

(2) @PropertySource

从指定的文件读取变量。示例代码会从resource目录下读取application.properties变量的值。文件的格式如下,既可以用常量,也可以用变量替换,来对不同环境的值作区分。

39fdff1df2b54c7bb74dd462ec5f5259

如何使用这个值?在要使用的地方获取即可。

40bf033e9be24f228489c94d2aecf292

(3) 与@Value配合使用

使用@Value可以把配置文件的值直接注入到成员变量中。

(4)通过@Import引用

在(1)的示例代码中,如果类上没有@PropertySource,但DemoConfig1或DemoConfig2中有@PropertySource,通过@Import可以将它们加载的变量也读出来。

(5)properties和.yml配置文件

@PropertySource只能导入.properties配置文件里的内容,对于.yml是不支持的。看了一些文章,得出结论是yml文件是不需要注解就能导入,但是需要路径。
Springboot有两种核心配置文件,application和bootstrap,都可以用properties或yml格式。区别在于bootstrap比application优先加载,并且不可覆盖。

(6)@MapperScan

这实际上是一个mybatis注解,作用是为指定路径下的DAO接口,通过sqlmapping.xml文件,生成实现类。

(7)@SpringBootApplication

@SpringBootApplication是由多个注解组合成的。源码如下:

1c91757e9d534ff79ef701eaeef94527

简单介绍一下这些注解:

1.元注解

最上面四行都是元注解。回忆一下它们的作用:

  • @Target 注解可以用在哪。TYPE表示类型,如类、接口、枚举
  • @Retention 注解的保留时间期限。只有RUNTIME类型可以在运行时通过反射获取其值
  • @Documented 该注解在生成javadoc文档时是否保留
  • @Inherited 被注解的元素,是否具有继承性,如子类可以继承父类的注解而不必显式的写下来。

2.@SpringBootConfiguration

标注这是一个SpringBoot的配置类,和@Configuration功能是相通的,从源码也可以看出它直接使用了@Configuration。
回忆一下,@Configuration注解的作用是,整合相关的@Bean来实现实例的声明,用以代替xml的形式。

3.@EnableAutoConfiguration

这个注解是实现自动化配置的核心注解,定义如下:

借助@Import引入的AutoConfigurationImportSelector,SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器。具体的细节这里不展开了,简单提一句,加载的是指定的配置文件中META-INF/spring.factories的配置。

4.@ComponentScan

扫描@Service、@Repository、@Component、@Controller等标注的类,创建bean。
可以设置扫描范围,决定类哪些生成bean,哪些类不生成。

5.@Import

将外部资源(bean、@Configuration配置类)导入到当前IOC容器中。
使用@Import便可以实例化引用的jar中定义的bean了。

4、Starter

指的是在依赖中引用的各种starter包。starter可以看作是“依赖jar+配置”打包的结果,目的是降低开发者引入组件的成本,不用自己梳理依赖、编写配置文件。
starter遵循“约定大于配置”的原则,使用的组件的配置大部分都有默认值,不声明也可以直接用。

创建一个Spring boot的简易步骤:

  1. 创建maven项目
  2. 创建proterties类来保存配置信息
  3. 编写业务功能类(包含会实例化为bean的类)
  4. 编写Configuration类,定义bean
  5. 在resources 文件夹下新建目录 META-INF,在目录中新建 spring.factories 文件,并且在
    spring.factories 中配置AutoConfiguration
  6. 打包

5、war包

(1)和jar包的区别

  • jar 把类和相关的资源封装
  • war 代表了一个可部署的Web应用程序

(2)SpringBoot项目打war包部署
通用步骤如下,其中1可能需要移除内嵌tomcat,2有其他形式,因为我工作时都是拿线程脚本打包的,没有实际操作过,下面步骤仅供参考。

  • pom.xml修改为按war打包
  • 修改main入口方法,继承一个SpringBootServletInitializer类,并且覆盖configure方法
  • maven打包
  • 复制到tomcat路径下(tomcat需要预先配置),使用startup启动

6、Springboot面试题补充

(1) 使用Springboot的两种方式

  1. 继承spring-boot-starter-parent项目
  1. 导入spring-boot-dependencies项目依赖
091f76490bee42b1ad3d6ac847327ba2
  1. SpringBoot 需要独立的容器运行吗?

可以不需要,内置了 Tomcat/Jetty等容器。
如何使用Jetty?排除掉Tomcat依赖并引入Jetty,并更改一些application配置。

  1. 运行 SpringBoot 有哪几种方式?

打包用命令或者放到容器中运行
用 Maven/ Gradle 插件运行
直接执行 main 方法运行

  1. SpringBoot启动时运行特定代码的方式

Bean实现接口 ApplicationRunner或者CommandLineRunner即可。

  1. SpringBoot实现热部署有哪几种方式?
    主要有两种:
    Spring Loaded —— 引用依赖(maven plugin)。对于注解和xml变动无法感知需要重启;
    Spring-boot-devtools —— 引用依赖、更改配置(可选)、启动idea的自动编译。注意生产环境插件可能导致gc。
  2. Spring Boot 可以兼容老 Spring 项目吗,如何做?
    可以兼容,使用 @ImportResource 注解导入老 Spring 项目配置文件。

7、 SpringBoot启动原理

SpringBoot的启动入口在main方法的SpringApplication.run(XXXApplication.class, args)处。
启动图:

35f740c10c5648a480a043a0ad2d59ff


简单总结下:

  • 注册各种环境变量配置
  • 注册各种工厂
  • 注册各种监听器
  • 创建上下文,初始化各种bean

其实知识都是学来的,多学些就行,工作中能学到的跟多,但是首先得有个好的工作,有个好的工作机会,而有个好的工作,又离不开技术的高低,技术的高低又得靠学习来提升,所以这都是相辅相成的,不给自己投资就得不到高的回报。

fc19675f95714126a2c240afbae02587
07ac971adf0147c087f636e5dc7601c3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值