spring常用注解
autowired与resource的区别
1、来源
@Resource由1.6以上版本的java提供
@Autowired由spring提供(org.springframework.beans.factory.annotation.Autowired)
2、注入方式
@Autowired默认按照byType 注入,也提供byName;@Resource默认按byName自动注入,也提供按照byType 注入
原理:反射
为什么有时候注解下面会有波浪线?
参考:https://www.cnblogs.com/joemsu/p/7688307.html
是因为spring建议使用构造器的方式注入,不推荐使用变量依赖注入
1、field(变量)注入
@Autowired
private ExcelExportService excelExportService;
优点:最常见的注入方式,变量方式注入非常简洁,没有任何多余代码,非常有效的提高了java的简洁性。即使再多几个依赖一样能解决掉这个问题。
缺点:1. 对于IOC容器以外的环境,除了使用反射来提供它需要的依赖之外,无法复用该实现类。而且将一直是个潜在的隐患,因为你不调用将一直无法发现NullPointException的存在
2. 可能会导致循环依赖
2、构造器注入
private final ExcelExportService excelExportService;
@Autowired
private ExcelExportController(ExcelExportService excelExportService){
this.excelExportService = excelExportService;
}
优点:spring4.X推荐的方式,构造器注入的方式能够保证注入的组件不可变,并且确保需要的依赖不为空。此外,构造器注入的依赖总是能够在返回客户端(组件)代码的时候保证完全初始化的状态。
依赖不可变:即注入对象为final。
依赖不为空:省去了对注入参数的检查,当要实例化FooController的时候,由于自己实现了有参数的构造函数,所以不会调用默认构造函数,那么就需要Spring容器传入所需要的参数,所以就两种情况:1、有该类型的参数->传入,OK 。2:无该类型的参数->报错。所以保证不会为空。
完全初始化状态:跟依赖不为空结合起来,向构造器传参之前,要确保注入内容不为空,那么肯定要调用依赖组件的方法来完成实例化,在java类加载实例化的过程中,如果有父类的话先初始化父类,然后到自己的成员变量,最后才是构造方法。所以返回的都是完全初始化的状态。
缺点:当参数过多的时候会显得臃肿。
3、setter注入
private ExcelExportService excelExportService;
@Autowired
private void setExcelExportService(ExcelExportService excelExportService){
this.excelExportService = excelExportService;
}
原因:构造器注入参数太多了,显得很笨重,另外setter的方式能用让类在之后重新配置或者重新注入。
自定义注解
参考:www.cnblogs.com/chanshuyi/p/annotation_serial_02_self_define_annotation.html
自定义注解可以分为三个部分: 注解体、元注解、注解属性。
注解体:
注解体是最简单的一个组成部分,只需要实例中一样有样学样即可。与接口的声明唯一的不同是在 interface 关键字前多了一个 @ 符号。
public @interface Verifiy {
}
元注解 :
元注解(meta-annotation)本身也是一个注解,用来标记普通注解的存留时间、使用场景、继承属性、文档生成信息。
元注解是一个特殊的注解,它是 Java 源码中就自带的注解。在Java 中只有四个元注解,它们分别是:@Target、@Retention、@Documented、@Inherited。
@Target注解
Target 注解限定了该注解的使用场景。
它有下面这些取值:
- ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
- ElementType.CONSTRUCTOR 可以给构造方法进行注解
- ElementType.FIELD 可以给属性进行注解
- ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
- ElementType.METHOD 可以给方法进行注解
- ElementType.PACKAGE 可以给一个包进行注解
- ElementType.PARAMETER 可以给一个方法内的参数进行注解
- ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
@Retention注解
Retention 注解用来标记这个注解的留存时间。
它其有四个可选值:
- RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
- RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
- RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
@Documented
@ Documented 注解表示将注解信息写入到 javadoc 文档中。
在默认情况下,我们的注解信息是不会写入到 Javadoc 文档中的。但如果该注解有 @Documented 标识,那么该注解信息则会写入到 javadoc 文档中。
@Inherited
@ Inherited注解标识子类将继承父类的注解属性。
在下面的例子中,我们声明了一个 Sweet 注解,接着在 Peach 类使用了 @Sweet 注解,但是并没有在 RedPeach 类使用该注解。
//声明一个Sweet注解,标识甜味。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Sweet {}
//桃子有甜味
@Sweet
public class Peach {}
//红色的水蜜桃
public class RedPeach extends Peach {}
虽然我们没在 RedPeach 类上使用了 @Sweet 注解,但是我们在 Sweet 注解声明中使用了 @Inherited 注解,所以 RedPeach 继承了 Peach 的 @Sweet 注解
注解属性
注解属性类似于类方法的声明,注解属性里有三部分信息,分别是:属性名、数据类型、默认值。
在 @Autowired 注解中就声明了一个名为 required 的 boolean 类型数据,其默认值是 true。
public @interface Autowired {
boolean required() default true;
}
需要注意的是,注解中定义的属性,它的数据类型必须是 8 种基本数据类型(byte、short、int、long、float、double、boolean、char)或者是类、接口、注解及它们的数组
什么场景需要自定义注解
校验,日志,统一操作,读写分离,是否启动动态数据源,自定义注解实现策略模式
swagger->config->扫描路径,控制接口显示
固定传参,spring(是否必传,正则校验)
bean加载过程
todo
spring springmvc springboot cloud的区别
strurs2、hibernate、mybatis的区别和特点
JPA 与 Spring Data JPA 与 Hibernate
参考:https://www.cnblogs.com/kangkaii/p/8458371.html
JPA是什么
- JPA的是 Java Persistence API 的简写,是Sun官方提出的一种ORM规范!
- Sun提出此规范有2个原因:
1.简化现有Java EE和Java SE应用开发工作。
2.Sun希望整合ORM技术,实现天下归一。 - 重点在于,JPA是一套规范,而不是具体的ORM框架。
- 故Hibernate、TopLink 等ORM框架 都是JPA的实现,其中Hibernate已获得Sun的兼容认证。
- JPA的标准的定制是hibernate作者参与定制的,所以JPA是Hibernate的一个总成。
- 优势在于:
1.开发者面向JPA规范的接口,但底层的JPA实现可以任意切换:觉得Hibernate好的,可以选择Hibernate JPA实现;觉得TopLink好的,可以选择TopLink JPA实现。
2.这样开发者可以避免为使用Hibernate学习一套ORM框架,为使用TopLink又要再学习一套ORM框架。 - 在项目中使用方式为:在实体类中,使用
@Entity
、@Table
、@Id
与@Column
等注解。
2.Spring Data JPA是什么?以及相关概述
-
首先Spring框架几乎是无所不能,无所不在。
-
其次Spring也想要做持久化相关工作,并且已有Spring-data-**这一系列包(Spring-data-jpa,Spring-data-template,Spring-data-mongodb等)。
-
其中Spring-data-jpa即代表着,Spring框架对JPA的整合。
-
Spring Data JPA是在JPA规范的基础下提供了Repository层的实现。
-
在项目中的repository层中具体表现为:
1.接口要继承JpaRepository
接口2.实现类无需显式实现
UserRepository
,只要命名为UserRepositoryImpl
即可。
好处在于对于不需要写sql或者sql语句不复杂(使用 @Query 注解可以实现的)的方法,不用重写。
对于需要判断并拼接查询条件的方法,我们可以在实现类中进行重写。
示例代码如下:
hibernate、mybatis、Spring Data JPA 技术选型?
更换数据库类型:mysql转oracle的时候,Spring Data JPA可以根据实体类自动生成数据库表。
支持的场景:mybatis更多
简单的增删改查的业务场景中Spring Data JPA比较占优势。
IOC、AOP
IOC实现方式是反射,AOP实现方式是动态代理
todo
IOC的缺点:通过反射机制,实例化对象,对性能有一定影响,创建对象过程变得复杂
IOC、AOP使用到的设计模式
AOP:使用动态代理(java、cglib)
IOC:工厂模式、观察者模式(监听器)、单例模式、策略模式、装饰着模式
todo
springcloud组件有哪些?
-
注册中心:eureka、nacos。nacos等于同时添加了Eureka和配置中心,不能和Eureka一起用
-
网关: zuul、nginx之间的差异?暴露微服务的网关系统,方便进行相关鉴权,安全控制,日志统一处理,易于监控的相关功能
-
Ribbon:负载均衡
-
分布式配置Spring Cloud Config,seata
-
hystrix:熔断器:监控调用情况,失败情况达到阈值,拒绝请求,进入半开状态
-
接口发现:openfeign
todo
mybatis中# 和 $ 的区别?
参考:https://blog.csdn.net/qq_19674263/article/details/104805603
1.#{}将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #{user_id},如果传入的值是111,那么解析成sql时的值为order by “111”, 如果传入的值是id,则解析成的sql为order by “id”.
2.将传入的数据直接显示生成在sql中。如:order by ${user_id},如果传入的值是111,那么解析成sql时的值为order by user_id, 如果传入的值是id,则解析成的sql为order by id.
3.#{}方式能够很大程度防止sql注入,而${}方式无法防止Sql注入。
4.${}方式一般用于传入数据库对象,例如传入表名,order by后的列名。
5.一般能用#的就别用$。
MyBatis排序时使用order by 动态参数时需要注意,用${}而不是#{}。