XML配置Bean,随着项目的扩大,我们需要把XML配置文件分放到不同的配置文件里
JDK1.5以后支持注解。例如:@Component、@Service。大大减少了配置量
最终的选择:应用基本配置使用XML,业务配置使用注解
Spring提供了Java配置的能力,使用Java配置可以让你更理解你配置的Bean
Spring4.x和Spring Boot都推荐使用Java配置
Spring框架提供了IOC容器、AOP、数据访问、Web开发、消息、测试等相关技术的支持
Spring提供了一个IOC容器用来初始化对象,解决对象间的依赖管理和对象的使用
每一个被Spring管理的Java对象都称之为Bean
Plan Old Java Object,即无任何限制的普通Java对象
Spring是模块化的,你可以只使用你需要的Spring的模块
Spring所有功能的设计和实现都是基于此四大原则的
控制翻转和依赖注入在Spring环境下是等同的概念,控制翻转是通过依赖注入实现的。
概念:是指容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖
目的:主要是为了解耦,体现一种“组合”的理念
SpringIOC容器创建Bean,通过容器将功能类Bean注入到你需要的Bean中。
Spring提供了xml、注解、Java配置、groxy配置实现Bean的创建和注入。
称之为元数据(即描述数据的数据)
元数据本身不具备任何可执行的能力,只能通过外界代码来对这些元数据行解析后进行一些有意义的操作。
全局配置使用Java配置
业务Bean的配置使用注解配置:@Service、@Component、@Repository、@Controller
在Spring容器中,只要容器中存在某个Bean,就可以在另外一个Bean的声明方法的参数中注入
概念:面向切面编程
目的:是为了解耦,可以让一组类共享相同的行为
Scope描述的是Spring容器如何新建Bean的实例,是通过@Scope注解来实现
概念:
Spring EL-Spring表达式语言,支持在xml和注解中使用表达式,类似于jsp的EL表达式
用途:
Spring开发中经常涉及调用各种资源的情况,包含普通文件、网址、配置文件、系统环境变量等
我们可以使用Spring的表达式语言实现资源的注入
用法:
Spring主要在注解@Value的参数中使用表达式
使用@PropertySource注解在类上,指明文件地址,然后@Value注入值
若使用@Value注入,还需要配置一个PropertySourcesPlaceholderConfigurer的Bean
Profile为在不同环境下使用不同的配置提供了支持
Spring的事件为Bean和Bean之间的消息通信提供了支持。当一个Bean处理完一个任务后,希望另外一个Bean知道并能做相应的处理,这时我们就需要让另外一个Bean监听当前Bean所发送的事件。
1、在pom文件中添加依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<optional>trueoptional>
<scope>truescope>
dependency>
2、左上角依次找到【File】——【Settings…】——【Build,Execution,Deployment】——【Compiler】
勾选"Build project automatically",然后右下角【Apply】——【OK】
3、使用 Ctrl+Shift+A 快捷键搜索"Registry",选择搜索出来的第一个:
4、找到"compiler.automake.allow.when.app.running",勾选,【Close】关闭:
5、重启项目,完事~
在实际项目中,你不可避免的要用到Spring容器本身的资源,这时你的Bean必须要意识到Spring容器的存在,才能调用Spring所提供的资源,这就是所谓的Spring Aware
是为了让Bean获得容器的服务
Spring通过任务执行器来实现多线程和并发编程。
使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor。
实际开发中任务一般是非阻碍的,即异步的,所以要在配置类中通过**@EnableAsync开启对异步任务的支持**,并通过在实际执行的Bean的方法中使用**@Async**注解来声明其是一个异步任务。
@Async如果注解在方法上,表明该类所有的方法都是异步方法。
首先通过在配置类注解@EnableScheduling来开启对计划任务的支持
然后在要执行计划任务的方法上注解@Scheduled来声明这是一个计划任务
spring通过@Scheduled支持多种类型的计划任务,包含cron、fixDelay、fixRate等
通过活动的profile,我们可以获得不同的Bean
Spring4提供了更通用的基于条件的Bean的创建,即使用@Conditional
@conditional根据满足某一个特定条件创建一个特定的Bean
元注解其实就是可以注解到别的注解的注解
就是被注解的注解称之为组合注解,组合注解具备元注解的功能
观察@Enable*注解的源码,发现所有的注解都有一个@Import注解,@Import是用来导入配置类的,者也就意味着这些自动开启的实现其实是导入了一些自动配置的Bean
单元测试只针对当前开发的类和方法进行测试
集成测试能够知道系统的各个部分组合在一起是否能正常工作
Spring通过Spring TestContext Framework对集成测试提供顶级支持。它不依赖于特定的测试框架,即可使用Junit,也可使用TestNG。
Model+View+Controller(数据模型+视图页面+控制器)
SpringMVC可以简单地开发灵活且松耦合的Web项目,和Spirng框架零配置结合
Presentation tier+Application tier+Data tier(展现层+应用层+数据访问层)
三层架构是整个应用框架,是由Spring框架负责管理的
MVC只存在于展现层
SpringMVC的ViewResolver,这是SpringMVC视图渲染的核心机制
SpringMVC里有个接口叫做ViewResolver,实现这个接口要重写方法resolveViewName( ),这个方法的返回值是接口View,而View的职责就是使用model、request、response对象,并将渲染的视图返回给浏览器。
静态资源需要直接访问,可以在配置里重写addResourceHandler方法来实现
可以让普通Bean实现HandlerInterceptor接口或者继承HandlerInterceptorAdapter类来实现自定义拦截器
通过重写WebMvcConfigurerAdapter的addInterceptors方法来注册自定义的拦截器
重写preHandler方法,在请求发生前执行
重写postHandler方法,在请求完成后执行
配置拦截器的Bean
重写addInterceptors方法,注册拦截器
通过@ControllerAdvice,我们可以将对于控制器的全局配置放置在同一个位置
注解了@Controller的类的方法可以使用**@ExceptionHandler**、@InitBinder、@ModelAttribute注解到方法上,这对所有注解了@RequestMapping的控制器内的方法有效
SpringMVC通过配置一个MultipartResolver来上传文件
通过MultipartFile file来接收文件,通过MultipartFile[ ] files接收多个文件上传
HttpMessageConverter是用来处理request和response里的数据的。
Spring为我们内置了大量的HttpMessageConverter。
SprinBoot通常有一个名为Application的入口类*,入口类里有一个main方法,这是标准的Java应用入口方法
@SpringBootApplication是SpringBoot的核心注解类,它是一个组合注解
@SpringBootApplication//核心注解类
public class Ch523Application {//入口类
//标准的java应用入口方法
public static void main(String[] args) {
SpringApplication.run(Ch523Application.class, args);
}
}
@SpringBootApplication注解源码上的注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration//主要的注解之一
@EnableAutoConfiguration//主要的注解之一
@ComponentScan//主要的注解之一
若不使用@SpringBootApplication注解,则需要在入口类上直接使用:
关闭特定的自动配置应该使用@SpringBootApplication注解的exclude参数
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
在SpringBoot启动时会有一个默认启动图案
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.6.RELEASE)
在src/main/resources下新建一个banner.txt
通过http://patorjk.com/software.taag网站生成字符,将生成的字符复制到banner.txt中
再次启动程序,图案将会发生变化
main里的内容修改为:
SpringApplication app = new SpringApplication(Ch523Application.class);
app.setShowBanner(false);
app.run(args);
或者使用fluent API修改为:
new SpringApplicationBuilder(Ch523Application.class)
.showBanner(false)
.run(args);
支持properties配置文件,支持yaml语言的配置文件
SpringBoot使用一个全局的配置文件application.properties或则application.yml
放置在src/main/resources目录或者类路径/config下
什么是yaml?
yaml是以数据为中心的语言,在配置数据的时候具有面向对象的特征
在src/main/resources目录下若两种配置文件同时存在,则properties配置文件优先
只要使用场景所需要的starter pom,相关的技术配置将会消除,就可以得到SpringBoot为我们提供额自动配置的Bean
SpringBoot提倡零配置,即无xml配置,但是在实际项目中,可能有一些特殊要求你必须使用xml配置,这时我们可以通过Spring提供的@ImportResource来加载xml配置
@ImportResource({"classpath:some-context.xml","classpath:another-context.xml"})
SpringBoot是可以基于jar包运行的,打成jar包的程序可以通过如下命令运行
java -jar xx.jar
或者通过命令修改Tomcat端口号
java -jar xx.jar --server.port=9090
在常规Spring环境下,注入properties文件里的值的方式:
@PropertySource指明properties文件的位置,然后通过@Value注入值
在SpringBoot环境下的操作:
在application.properties文件里定义属性,然后直接使用@Value注入即可
SpringBoot还提供了基于类型安全的配置方式,通过**@ConfigurationProperties将properties属性和一个Bean基于属性**关联,从而实现类型安全的配置
SpringBoot支持Java Util Logging、Log4j、Log4j2和Logback作为日志框架
无论使用哪种,SpringBoot一位当前使用日志空间的控制台输出及文件输出做好了配置。
默认情况下,SpringBoot使用Logback作为日志框架
配置日志文件:
logging.file = D:/mylog/log.log
配置日志级别,格式为logging.level.包名=级别
logging.level.org.springframework.web = DEBUG
Profile是Spring用来针对不同的环境对不同的配置提供支持的
全局Profile配置使用application-{profile}.properties。例如:application-prod.properties
通过在application.properties中设置spring.profiles.active=prod来指定活动的Profile
SpringBoot关于自动配置的源码位于org.springframework.boot:spring-boot:2.1.1RELEASE下
三种方式查看当前项目中已启用和未启用的自动配置的报告
java -jar xx.jar --debug
debug = true
书P152看图
首先看**@SpringBootApplication**注解
这是一个组合注解,他的核心功能是由**@EnableAutoConfiguration**注解提供
@EnableAutoConfiguration源码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})//关键功能
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
这里的关键功能是**@Import注解导入的配置功能**
AutoConfigurationImportSelector使用SpringFactoriesLoader.loadFactoryNames方法
来扫描具有META-INF/spring.factories文件的jar包
而org.springframework.boot:spring-boot:2.1.1RELEASE里就有一个spring.factories文件
此文件声明了有哪些自动配置。
SpringBoot提供了spring-boot-starter-web为Web开发予以支持
spring-boot-starter-web提供了嵌入的Tomcat以及SpringMVC的依赖
Web相关的自动配置存储在spring-boot-autoconfigure.jar的org.springframework.boot.autoconfigure.web下
SpringBoot推荐使用Thymeleaf模板引擎,因为Thymeleaf提供了完美的SpringMVC的支持
因为jsp在内嵌的Servlet容器上运行有问题,内嵌的容器不支持以jar的形式运行jsp,Undertow不支持jsp
Thymeleaf是一个Java类库,是一个xml/xhtml/html5模板引擎,可以作为MVC的Web应用View层
还提供额外的模块与SpringMVC集成,所以可以完全替代jsp
<html xmlns:th="http://www.thymeleaf.org">
html>
<link th:src="@{bootstrap/css/bootstrap.min.css}" rel="stylesheet"/>
<span th:text="${singlePerson.name}">span>
<li th:each="person:${people}">
<span th:text="person.name">span>
<span th:text="person.age">span>
li>
<div th:if="${not #lists.isEmpty(people)}">
div>
<script th:inline="javascript">
//让JavaScript代码能够访问model中的属性
var single=[[${ singlePerson }]]
script>
<button th:onclick="'getName(\"+${person.name}+'\')'">获得名字button>
通过查看WebMvcAutoConfiguration和WebMvcProperties的源码
在自动配置类的addResourceHandlers方法中定义了以下静态资源的自动配置
类路径文件
把类路劲下的/static、/public、/resources和META-INF/resources文件夹下的静态文件直接映射为 /**
可以通过http://localhost:8080/**来访问
webjar
webjar就是将我们常用的脚本框架封装在jar包中的jar包
把webjar的/META-INF/resources/webjars/下的静态文件映射为/webjar/**
可以通过http://localhost:8080/webjar/**来访问
3)、自动配置的Formatter和Converter
只要我们定义了Converter、GenericConverter和Formatter接口的实现类的Bean
这些Bean就会自动注册到SpringMVC中。
如果要新增自定义的HttpMessageConverter
只需要定义一个你自己的HttpMessageConverters的Bean
然后在此Bean中注册自定义HttpMessageConverter即可
把静态index.html文件放置在如下目录(任意即可)
访问http://localhost:8080/时,会直接映射
在SpringBoot提供SpringMVC默认配置不符合你的需求时,则可以通过一个配置类(注解有@Configuration的类)加上@EnableWebMvc注解来实现完全自己控制的MVC配置
在既要保留SpringBoot的默认MVC配置,又需要增加自己的额外的配置的时候,可以定义一个配置类并继承WebMvcConfigurerAdapter,无需使用@EnableWebMvc注解,然后按照SpringMVC的配置方法来添加SpringBoot为我们所做的其他配置
当使用嵌入式的Servlet容器时,通过将Servlet、Filter、和Listener声明为Spring Bean而达到注册的效果
或者注册ServletRegistrationBean、FilterRegistrationBean和ServletListenerRegistrationBean的Bean
Tomcat的所有属性都在org.springframework.boot.autoconfigure.web.ServerProperties配置类中做了定义
我们只需要在application.properties文件里配置属性做配置即可
容器配置都已servlet作为前缀,Tomcat特有配置都以servlet.tomcat作为前缀
# 配置Servlet容器
# 配置端口号,默认为8080
server.port=8090
# 用户会话session的过期时间,秒为单位
server.servlet.session.timeout=30
# 配置访问路径,默认为/
server.servlet.context-path=/hello
# 配置Tomcat编码,默认为utf-8
server.tomcat.uri-encoding=utf-8
# 配置Tomcat是否开启压缩,默认为关闭off
server.tomcat.compression=off
如果需要通过代码的方式配置servlet容器,则可以注册一个实现EmbeddedServletContainerCustomizer接口的Bean
若想直接配置Tomcat、Jetty、Undertow,则可以直接定义TomcatEmbeddedServletContainerFactory、JettyEmbeddedServletContainerFactory、UndertowEmbeddedServletContainerFactory
SpringBoot默认使用Tomcat
替换为Jetty:
在ppm.xml中,将spring-boot-starter-web的依赖
由spring-boot-starter-tomcat修改为spring-boot-starter-Jetty
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-tomcatartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jettyartifactId>
dependency>
替换为Undertow:
在ppm.xml中,将spring-boot-starter-web的依赖
由spring-boot-starter-tomcat修改为spring-boot-starter-Undertow
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-tomcatartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-undertowartifactId>
dependency>
SSL(Secure Sockets Layer,安全套接层)是位网络通信提供安全及数据完整性的一种安全协议,SSL在网络传输层对网络连接进行加密
SSL协议位于TCP/IP协议与各种应用层协议之间,为数据提供安全支持。
SSL协议分为两层:
在基于B/S的Web应用中,是通过HTTPS来实现SSL的。
在HTTP下加入SSL层,HTTPS的安全基础是SSL。
HTTPS是以安全为目标的http通道,是http的安全版本。
书P193
将.keystore文件复制到整个项目的根目录下(不是src,是更外面一层的)
然后在application.properties做如下配置
server.port = 8443
server.ssl.key-store = .keystore
server.ssl.key-store-password = 123456
server.ssl.key-store-type = JKS
server.ssl.key-alias = tomcat
启动SpringBoot项目,并访问https://localhost:8443
3、http转向https
需要配置TomcatEmbeddedServletContainerFactory,并且添加Tomcat的connector来实现
书P195
完成后,访问http://localhost:8080/即可跳转到https://localhost:8443
SpringBoot已经提供了默认的Favicon,每次访问都能看见
在application.properties中设置关闭Favicon,默认为开启
spring.mvc.favicon.enabled = false
将自己的favicon.ico(文件名是固定的)文件放置在
即可使用自己的favicon.ico
WebSocket为浏览器和服务端提供了双工异步通信的功能,即双向通信。WebSocket需要浏览器的支持
WebSocket是通过一个socket来实现双工异步通信能力的
我们使用它的子协议STOMP,它是一个更高级的协议
STOMP协议使用一个基于帧(frame)的格式来定义消息
类似于request和response(类似于@RequestMapping的@MessageMapping)
SpringBoot为WebSocket提供的stater pom是spring-boot-starter-websocket
广播式:服务端有消息时,会将消息发送给所有连接当前endpoint的浏览器
点对点式
现代B/S系统特色:
Boostrap是开发响应式和移动优先的Web应用
SpringBoot Data是一个伞形项目,包含了大量的关系型数据库和非关系型数据库的数据访问解决方案
SpringData为我们使用统一的API来对上述的数据存储技术进行数据访问操作提供了支持
Spring Data Commons使用基于Spring统一标准CRUD(创建、获取、更新、删除)
查询、排序、分页的相关操作
Spring Data Commons的一个重要概念:Spring Data Repository抽象。使用Spring Data Repository可以极大的减少数据访问层的代码。
Spring Data可以根据属性名进行计数、删除、查询方法等操作
首先认识Hibernate:Hibernate使用O/R映射(Object-Relational Mapping)技术实现数据访问。
O/R映射即将领域模型和数据库的表进行映射,通过程序操作对象而实现表数据操作的能力,让数据访问操作无需关注数据库相关的技术。
JPA即Java Persistence API。是一个基于O/R映射的标准规范。
JPA的主要实现由Hibernate、EclipseLink、OpenJPA等。
Spring Data JPA是Spring Data的一个子项目。它通过提供基于JPA的Repository极大的减少了JPA作为数据访问方案的代码量。
使用Spring Data JPA建立数据访问层,只需定义一个继承JpaRepository的接口
public interface PersonRepository extends JpaRepository<Person,long>{
//定义数据访问操作的方法
}
在Spring环境中,通过**@EnableJpaRepositories注解**开启Spring Data JPA的支持
@EnableJpaRepositories接收的value参数用来扫描数据访问层所在包下的数据访问的接口定义
Spring Data JPA支持通过定义在Repository接口中的方法名来定义查询,而方法名是根据实体类的属性名来确定的
1)常规查询
//通过名字相等查询,参数为name
//相当于JPQL:select p from Person p where p.name=?
List<Person> findByName(String name);
//通过名字like查询,参数为name
//相当于JPQL:select p from Person p where p.name like ?
List<Person> findByNameLike(String name);
//通过名字和地址查询,参数为name和address
//相当于JPQL:select p from Person p where p.name=? and p.address=?
List<Person> findByNameAndAddress(String name,String address);
查询关键字
关键字 | 示例 | 同功能 |
---|---|---|
And | FindByLastnameAndFirstname | where x.lastname=? and firstname=? |
Or | FindByLastnameOrFirstname | |
Is,Equals | FindByFirstname,fingByFirstnameIs, findByFirstnameEquals | |
Between | ||
LessThan | ||
LessThanEqual | ||
GreaterThan | ||
GreaterThanEqual | ||
After | ||
Before | ||
IsNull | ||
IsNotNull,NotNull | ||
Like | ||
NotLike | ||
StartingWith | ||
EndingWith | ||
Containing | ||
OrderBy | ||
Not | ||
In | ||
NotIn | ||
True | findByActiveTrue( ) | |
False | findByActiveFalse( ) | |
IgnoreCase | findByFirstnameIgnoreCase |
2)限制结果数量
结果数量是用 top 和或 first 关键字来实现的
//获得符合查询条件的前10条数据
List<Person> findFirst10ByName(String name);
//获得符合查询条件的前30条数据
List<Person> findTop30ByName(String name);
支持用JPA的**@NamedQuery来定义查询方法**,即一个名称映射一个查询语句
@Entity
@NamedQuery(name = "Person.findByName"),query="select p from Person p where p.name=?"
public class Person{
}
使用如下语句
public interface PersonRepository extends JpaRepository<Person,Long>{
//使用的是NamedQuery里定义的查询语句,而不是根据方法名称查询
List<Person> findByName(String name);
}
1)使用参数索引
JPA支持用**@Query注解在接口的方法上**实现查询
public interface PersonRepository extends JpaRepository<Person,Long>{
@Query("select p from Person p where p.address=?")
List<Person> findByAddress(String address);
}
2)使用命名参数
JPA支持在语句里用名称来匹配查询参数
public interface PersonRepository extends JpaRepository<Person,Long>{
@Query("select p from Person p where p.address=:address")
List<Person> findByAddress(@Param("address")String address);
}
3)更新查询
JPA支持 @Modifying 和 @Query 注解组合来事件更新查询
public interface PersonRepository extends JpaRepository<Person,Long>{
@Modifying
@Transactional
@Query("update Person p set p.name=?")
int setName(String name);
//返回值int表示更新语句影响的行数
}
JPA提供了基于准则查询的方式,即Criteria查询
而Spring Data JPA提供了一个Specification接口构造准则查询,Specification接口定义了一个toPredicate方法用来构造查询条件
1)定义
//接口类必须实现JpaSpecificationExexutor接口
public interface PersonRepository extends JpaRepository<Person,Long>,JpaSpecificationExexutor<Person>{
}
//然后需要定义Criterial查询
public class CustomerSpecs{
//查出所有来自苏州的人
public static Specification<Person> personFromSuzhou(){
return new Specification<Person>(){
@Override//通过root获得需要查询的属性,通过CriteriaBuilder构造查询条件
public Predicate toPredicate(Root<Person> root,CriteriaQuery<?> query,CriteriaBuilder cb){
return cb.equal(root.get("address"),"苏州");
}
};
}
//Predicate、Root、CriteriaQuery、CriteriaBuilder都是来自JPA的接口
}
2)使用
//静态导入
import static com.wisely specs.CustomerSpecs.*;
//注入personRepository的Bean后
List<Person> people=personRepository.findAll(personFromSuzhou);
JPA充分考虑在实际开发中所必须的排序和分页场景,提供了Sort类、Page接口和Pageable接口
1)定义
public interface PersonRepository extends JpaRepository<Person,Long>{
List<Person> findByName(String name,Sort sort);
Page<Person> findByName(String name,Pageable pageable);
}
2)使用排序
List<Person> people=personRepository.findByName("xx",new Sort(Direction.ASC,"age"));
3)使用分页
List<Person> people=personRepository.findByName("xx",new PageRequest(0,10));
//其中page接口还可以获得当前页面的记录、总页数、总记录数、是否有上一页或下一页等
(1)定义自定义Repository接口
@NoRepositoryBean//此注解指明当前这个接口不是我们领域类的接口(例如Repository)
public interface CustomRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>{
//我们自定义的Repository实现PagingAndSortingRepository具备排序和分页的能力
public void doSomething(ID id);//要定义的数据操作方法在接口中定义
}
(2)定义接口实现
public class CustomRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CustomRepository<T, ID>{
//首先实现CustomRepository接口,继承SimpleJpaRepository类让我们可以使用其提供的方法(如findAll)
private final EntityManager entityManager;//让数据操作方法中可以使用entityManager
public CustomRepositoryImpl<Class<T> domainClass,EntityManager entityManager>{
//有参构造函数
this.entityManager = entityManager;
}
public void doSomething(ID id){
//定义数据访问操作,如调用findAll方法并构造一些查询条件
}
}
(3)自定义RepositoryFactoryBean
(4)开启自定义支持使用@EnableJpaRepository的repositoryFactoryBeanClass来指定FactoryBean即可
@EnableJpaRepository(repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class)