1. @Enable*注解
1.1. 注解描述
@EnableAspectJAutoProxy - 开启对AspectJ自动代理技术
@EnableConfigurationProperties - 开启对@ConfigurationProperties注解配置Bean的支持
@EnableJpaRepositories - 开启对Spring data JPA Repository的支持
@EnableTransactionManagement 开启注解式事务的支持,比如在某个公有方法中添加@Transactional
通过简单的@Enable*来开启一项功能的支持,从而避免自己配置大量的代码,大大降低使用难度。
1.2. 简单使用
1.2.1. @EnableAspectJAutoProxy
1)使用xml时的配置:
<aop:aspectj-autoproxy expose-proxy="true" proxy-target-class="true"/>
属性说明:
①boolean proxyTargetClass() default false;
描述:启用cglib代理,proxyTargetClass默认为false。
②boolean exposeProxy() default false;
描述:如果在一个方法中,调用内部方法,需要在调用内部方法时也能够进行代理,比如内部调用时,使用
(IService)AopContext.currentProxy().sayHello(),需要将exposeProx设置为true,默认为false。
2)使用注解@EnableAspectJAutoProxy配置
@EnableAspectJAutoProxy(proxyTargetClass=true, exposeProxy=true)
@SpringBootApplication
public class BootStrap {
public static void main(String[] args) {
SpringApplication.run(BootStrap.class, args);
}
}
注:也可以不使用@EnableAspectAutoProxy注解开启AspectJ自动代理技术,可以在spring boot的默认配置appllication.properties中进行配置,配置如下:
# 增加@EnableAspectJAutoProxy
spring.aop.auto=true
# 开启CGLIB代理
spring.aop.proxy-target-class=true
1.2.2. @ConfigurationProperties
通过@ConfigurationProperties将properties属性和一个Bean及其属性关联,从而实现类型安全的配置
在appllication.properties中添加如下配置:
spring.http.encoding=utf-8
2)类型安全的Bean
@Component
@ConfigurationProperties(prefix="spring.http")
public class SpringEncoding {
private String encoding;
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
}
注:@ConfigurationProperties既可以放在类上也可以放在方法上,放在方法上使用和类上一样。@ConfigurationProperties加载properties文件内的配置,通过prefix属性指定properties配置的前缀,通过locations指定properties文件所在路径,例如:
@Component
@ConfigurationProperties(prefix="spring.http", locations={"classpath:encoding.properties"})
public class SpringEncoding {
private String encoding;
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
}
1.2.3. @EnableJpaRepositories和EnableTransactionManagement
1)使用xml配置:
2)使用EnableJpaRepositories和EnableTransactionManagemen注解
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryDemo",
transactionManagerRef = "transactionManagerDemo",
basePackages = {"com.happygo.gitlab.domain.demo.repository"})
@Profile(value = {"dev", "serverForDev"})
public class DataSourceConfig {
@Autowired
private JpaProperties jpaProperties;
@Autowired
@Qualifier("demohDS")
private DataSource demoDataResource;
@Bean(name = "entityManagerDemo")
@Primary
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Bean(name = "entityManagerFactoryDemo")
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(schDataResource)
.properties(getVendorProperties(schDataResource))
.packages("com.happygo.sample.domain.sch.entity") //设置实体类所在位置
.persistenceUnit("schPersistenceUnit")
.build();
}
private Map<String, String> getVendorProperties(DataSource dataSource) {
return jpaProperties.getHibernateProperties(dataSource);
}
@Bean(name = "transactionManagerDemo")
@Primary
PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
注:@Configuration指定这个bean为配置类,相当于某个Spring xml文件配置,@Bean声明为一个bean,相当于xml中的<bean></bean>,@Primary默认级别,@Profile是一条条件化配置,基于运行时激活的Profile,会使用或者忽略不同的Bean或配置类。@EnableJpaRepositories中的属性entityManagerFactoryRef 对应于xml文件中的红色字体①处,transactionManagerRef对应于②处,basePackages对应于红色字体③处。
1.2.4. @EnableConfigurationProperties
见5.2.简单使用
2. Profile配置
当应用程序需要部署到不同的运行环境时,一些配置细节会有所不同,比如数据连接的细节在开发环境和测试环境下就会不一样,Spring框架从3.1开始支持基于Profile的配置。Profile是一条条件化的配置,基于运行时激活的Profile,会使用或者或略不同的Bean或配置类。
全局Profile配置使用application-{profile}.properties(如application-prod.properties)
1)在apllication.properties添加配置:
spring.profiles.active=dev
2)@Profile在配置类中使用:
@Configuration
@EnableConfigurationProperties(HelloServiceProperties.class)
@ConditionalOnClass(HelloService.class)
@ConditionalOnProperty(prefix="hello", value="enabled", matchIfMissing=true)
@Profile("dev")
public class HelloServiceAutoConfiguration {
@Autowired
private HelloServiceProperties helloServiceProperties;
@Bean
@ConditionalOnMissingBean(HelloService.class)
public HelloService helloService(){
HelloService helloService = new HelloService();
helloService.setMsg(helloServiceProperties.getMessage());
return helloService;
}
}
注:如果Profile=prod(生产环境),这个配置类就会忽略。
3. Spring MVC常用注解
3.1. 注解描述
①@Controller
这个注解我们很常见,加了这个注解我们就知道这是一个控制器,DispatchServlet会自动扫描注解了此注解的类,并将Web请求映射到注解了@RequestMapping的方法上,这里特别指出,在声明普通Bean对象时,使用@Component、@Service、@Repository和@Controller是等同的,因为@Service、@Repository和@Controller都组合了@Component元注解,但在Spring MVC中声明控制器bean,只能只用@Controller
②@RequestMapping
@RequestMapping注解是用来映射Web请求(访问路径和参数)、处理类和方法的。@RequestMapping可注解在类或者方法上,注解在方法上的@RequestMapping路径会继承注解在类上的路径
③ResponseBody
@ResponseBody支持将返回值放在response体内,而不是返回一个页面。此注解可放置在返回值前或者方法上
④RequestBody
@RequestBody允许request的参数在reques体内,而不是链接在地址后面,此注解放置在参数前
⑤@RestController
@RestController是一个组合注解,组合了@Controller和@ResponseBody如果在类中加了@RestController就无需在添加@ResponseBody注解,SpringMVC就会自动将实体对象转换成xml或者json等媒体类型.
3.2. 简单使用
请见(报文转换工程中的controller包)
4. 多数据源配置
4.1. 配置数据源(两个)
@Configuration
public class DataSourceConfig {
@Bean(name = "primaryDS")
@Qualifier("primaryDS")
@Primary @ConfigurationProperties(prefix="spring.primary.datasource")
public DataSource primaryDataSource(){
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryDS")
@Qualifier("secondaryDS") @ConfigurationProperties(prefix="spring.secondary.datasource")
public DataSource secondaryDataSource(){
return DataSourceBuilder.create().build();
}
}
1)将数据源通过java配置的形式配置,数据库的连接地址url、密码、账户等通过注解@ConfigurationProperties绑定,这些属性配置在application.properties文件中
2)@Primary注解为默认级别,加了该注解会默认使用声明的bean
3)@Qualifier注解,如果有多个类型一样的bean,就可以通过@Qualifier注明名称区分
4)DataSourceBuilder类是Spring Boot中提供的用于创建数据源的类
4.2. 配置事务管理器等配置
具体的java配置见1.2.3,下面对1.2.3中的java配置做详细解释
1)片段一
@Autowired
private JpaProperties jpaProperties;
说明:Spring Boot启动时会将JPA的默认属性值值与JpaProperties进行关联,如果想改变默认属性值,可以通过在application.properties文件中添加相关属性,前缀必须为spring.jpa,JpaProperties相关属性如下:
spring.jpa.database | 要操作的目标数据库,默认自动检测,也可以通过databasePlatform属性设置 |
spring.jpa.database-platform | 要操作的目标数据库,默认自动检测,也可以通过Database枚举设置 |
spring.jpa.generate-ddl | 启动时要初始化schema(默认为false) |
spring.jpa.hibernate.ddl-auto | DDL模式(none、validate、update、create和create-drop),这是hibernate.hbm2ddl.atuto属性的一个快捷方式,在使用嵌入式数据库时,默认为create-drop,其他情况为none |
spring.jpa.hibernate.naming-strategy | Hibernate命名策略全限定类名 |
spring.jpa.open-in-view | 注册OpenEntityManagerInViewInterceptor,在请求的这个处理过程中,将一个JPAEntityManager绑定到线程(默认值为true) |
spring.jpa.properties | JPA提供方要设置的额外原生属性 |
spring.jpa.show-sql | 在使用Bitronix Transaction Manager时打开SQL语句的日志(默认为false) |
2)片段二:
private Map<String, String> getVendorProperties(DataSource dataSource){
return jpaProperties.getHibernateProperties(dataSource);
}
说明:用于获取hibernate出厂属性
3)片段三:
@Bean(name = "entityManagerFactorySch")
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(schDataResource)
.properties(getVendorProperties(schDataResource))
.packages("com.happygo.pss.sample.domain.sch.entity") //设置实体类所在位置
.persistenceUnit("schPersistenceUnit")
说明:EntityManagerFactoryBuilder设置数据源,hibernate属性,实体所在包位置及持久化单元,通过build方法返回一个LocalContainerEntityManagerFactoryBean。
片段四:
@Bean(name = "entityManagerSch")
@Primary
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
说明:通过片段三生成的实体管理工厂类去创建实体管理类,用于对持久化对象进行数据操作。
5. Spring Boot核心注解
5.1. 注解描述
@ConditionalOnBean:当容器里有指定的Bean条件下
@ConditionalOnClass:当类路径下有指定的类的条件下
@ConditionalOnExpression:基于SPEL表达式作为判断条件
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置
@ConditionalOnMissingBean:当容器里没有指定Bean的情况下
@ConditionalOnMissingClass:当类路径下没有指定的类的条件下
@ConditionalOnNotWebApplication:当前项目不是web项目的条件下
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径下是否有指定的值
@ConditionalOnWebApplication:当前项目是Web项目条件下
5.2. 简单使用
自定义自己的自动化配置
1)属性配置
@ConfigurationProperties(prefix="hello")
public class HelloServiceProperties {
private static final String MSG = "word";
private String message = MSG;
public String getMessage() {
return message;
}
public void setMessage(String msg) {
this.message = msg;
}
}
2)判断依据类
public class HelloService {
private String msg;
public String sayHello(){
return "hello " + msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
3)自动配置类
@Configuration
@EnableConfigurationProperties(HelloServiceProperties.class)
@ConditionalOnClass(HelloService.class)
@ConditionalOnProperty(prefix="hello", value="enabled", matchIfMissing=true)
@Profile("dev")
public class HelloServiceAutoConfiguration {
@Autowired
private HelloServiceProperties helloServiceProperties;
@Bean
@ConditionalOnMissingBean(HelloService.class)
public HelloService helloService(){
HelloService helloService = new HelloService();
helloService.setMsg(helloServiceProperties.getMessage());
return helloService;
}
}
注:根据HelloServiceProperties提供的参数,并通过@Conditional判断HelloService这个类是否存在,且当容器中没有这个Bean的情况下自动配置这个Bean。
1)注册配置
若想自动配置生效,需要注册自动配置类,在src/main/resources下新建META-INF/spring.factories,添加如下内容:
com.happygo.samples.config.HelloServiceAutoConfiguration
6.内存数据库
在使用内存数据库的时候,你需要引入H2的依赖包,如果是通过JPA的方式去操作数据库,你需要引入spring-boot-starter-data-jpa起始依赖,H2内存数据库在Spring Boot启动时就能使用,启动时H2采用的是默认配置。
6.1. 实现h2本地化
H2在程序重新启动后,数据就会消失,有些时候我们需要数据能一直存在,那么你就可以在application.properties文件中进行配置:
spring.datasource.url=jdbc:h2:file:D:\\test\\db\\testDB
spring.datasource.username = sa
spring.datasource.password = sa
spring.datasource.driverClassName = org.h2.Driver
6.2. hsqldb替换H2
替换h2使用hsqldb,需要修改maven的pom文件,覆盖掉h2的maven依赖:
<!-- 内存数据库hsqldb -->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
6.@ControllerAdvice
通过@ControllerAdivce,我们可以对于控制台的全局配置放置在一个位置,注解了@Controller的类使用@ExceptionHandler、@InitBinder注解到方法上,这对所有注解了@RequestMapping的控制器内的方法有效。
@ExceptionHandler:用于对全局处理控制器的异常
@InitBinder:用来设置WebDataBinder,WebDataBinder用来自动绑定前台请求参数到Model中
示例:
定制ControllerAdvice
@ControllerAdvice
public class HandleExceptionController {
/**
* 捕捉所有Controller中的异常
*/
@ResponseBody
@ExceptionHandler({PatternException.class, BusinessValidateException.class, Exception.class})
public CommonResult handleException(Exception e){
CommonResult result = new CommonResult();
if(e instanceof PatternException){
LogUtil.getAppLogger().info("格式校验异常, " + e.getMessage());
result.setCode(CodeEnum.PATTERN_ERROR.getCode());
result.setMessage(e.getMessage());
}else if(e instanceof BusinessValidateException){
LogUtil.getAppLogger().info("业务校验异常, " + e.getMessage());
result.setCode(((BusinessValidateException) e).getErrorCode());
result.setMessage(e.getMessage());
}else{
LogUtil.getAppLogger().error("系统异常, " + e);
result.setCode(CodeEnum.SYSTEM_ERROR.getCode());
result.setMessage(CodeEnum.SYSTEM_ERROR.getMessage());
result.setErrors("系统异常");
}
return result;
}
}