springboot系列五、springboot常用注解使用说明
一、controller相关注解
1、@Controller
控制器,处理http请求。
2、@RespController
Spring4之后新加的注解,原来返回json需要@ResponseBody和@Controller配合。
3、@RequestMapping
配置url映射,用于方法和controller类上。
4、@GetMapping
注解简写:@RequestMapping(value = "/say",method = RequestMethod.GET)等价于:@GetMapping(value = "/say")
二、取值
1、@PathVariable:获取url中的数据
方式1:
@Controller @RequestMapping("/User") public class HelloWorldController { @RequestMapping("/getUser/{uid}") public String getUser(@PathVariable("uid")Integer id, Model model) { System.out.println("id:"+id); model.addAttribute("userName","小明"); model.addAttribute("phone","123456"); return "user"; } }
访问url:
http://192.168.1.100:8082/User/getUser/1111
方式2:
@Controller @RequestMapping("/User") public class HelloWorldController { @RequestMapping("{uid}/getUser") public String getUser(@PathVariable("uid")Integer id, Model model) { System.out.println("id:"+id); model.addAttribute("userName","小明"); model.addAttribute("phone","123456"); return "user"; } }
访问url:
http://192.168.1.100:8082/springboot-demo/User/1111/getUser
2、@RequestParam:获取请求参数的值
@Controller @RequestMapping("/User") public class HelloWorldController {
@RequestMapping("/getUser") public String getUser(@RequestParam("uid")Integer id, Model model) { System.out.println("id:"+id); model.addAttribute("userName","小明"); model.addAttribute("phone","123456"); return "user"; } }
url:
http://192.168.1.100:8082/springboot-demo/User/getUser?uid=112
三、启动注解
1、@SpringBootApplication
源码:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication { .... }
发现@SpringBootApplication
是一个复合注解,包括@ComponentScan
,和@SpringBootConfiguration
,@EnableAutoConfiguration
。
2、@SpringBootConfiguration
继承自@Configuration
,二者功能也一致,标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean
注解标记的方法的实例纳入到srping
容器中,并且实例名就是方法名。
3、@EnableAutoConfiguration
@EnableAutoConfiguration
的作用启动自动的配置,@EnableAutoConfiguration
注解的意思就是Springboot
根据你添加的jar包来配置你项目的默认配置,比如根据spring-boot-starter-web
,来判断你的项目是否需要添加了webmvc
和tomcat
,就会自动的帮你配置web项目中所需要的默认配置。
4、@ComponentScan
扫描当前包及其子包下被@Component
,@Controller
,@Service
,@Repository等
注解标记的类并纳入到spring容器中进行管理。是以前的<context:component-scan>
(以前使用在xml中使用的标签,用来扫描包配置的平行支持)。所以本demo中的User为何会被spring
容器管理。
5、@ConfigurationProperties和@PropertySourceproperties配置文件映射到实体bean
Spring Boot可使用注解的方式将自定义的properties文件映射到实体bean中,比如smsConfig.properties文件
sms.code=17788990
sms.content=消息不存在
SmsConfig.java
@Configuration @ConfigurationProperties(prefix = "sms") @PropertySource("classpath:/config/smsConfig.properties") public class SmsConfig { private String code; private String msg; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
只需要该类被扫描到即可。使用@Autowired注入。
@Autowired private SmsConfig smsConfig;
6、@EnableConfigurationProperties
如果是其他非扫描路径,在Spring Boot的启动类上面加注解
@EnableConfigurationProperties({SmsConfig.class}) 即可,用法一样。
7、@ConditionalOnClass
当spring中已经加载某个类时该配置生效,用法:
@ConditionalOnClass({SmsConfig.class})
8、@ConditionalOnProperty
这个注解能够控制某个configuration是否生效。具体操作是通过其两个属性name以及havingValue来实现的,其中name用来从application.properties中读取某个属性值,如果该值为空,则返回false;如果值不为空,则将该值与havingValue指定的值进行比较,如果一样则返回true;否则返回false。如果返回值为false,则该configuration不生效;为true则生效。
@Configuration //如果synchronize在配置文件中并且值为true @ConditionalOnProperty(name = "synchronize", havingValue = "true") public class SecondDatasourceConfig { @Bean(name = "SecondDataSource") @Qualifier("SecondDataSource") @ConfigurationProperties(prefix = "spring.second.datasource") public DataSource jwcDataSource() { return DataSourceBuilder.create().build(); } }
9、同类型注解
- @ConditionalOnClass : classpath中存在该类时起效
- @ConditionalOnMissingClass : classpath中不存在该类时起效
- @ConditionalOnBean : DI容器中存在该类型Bean时起效
- @ConditionalOnMissingBean : DI容器中不存在该类型Bean时起效
- @ConditionalOnSingleCandidate : DI容器中该类型Bean只有一个或@Primary的只有一个时起效
- @ConditionalOnExpression : SpEL表达式结果为true时
- @ConditionalOnProperty : 参数设置或者值一致时起效
- @ConditionalOnResource : 指定的文件存在时起效
- @ConditionalOnJndi : 指定的JNDI存在时起效
- @ConditionalOnJava : 指定的Java版本存在时起效
- @ConditionalOnWebApplication : Web应用环境下起效
- @ConditionalOnNotWebApplication : 非Web应用环境下起效
四、bean注入相关
1、@Repository
DAO层注解,DAO层中接口继承JpaRepository<T,ID extends Serializable>,需要在build.gradle中引入相关jpa的一个jar自动加载。
2、@Service
- @Service是@Component注解的一个特例,作用在类上
- @Service注解作用域默认为singleton
- 使用注解配置和类路径扫描时,被@Service注解标注的类会被Spring扫描并注册为Bean
- @Service用于标注业务层组件,表示定义一个bean
- @Service使用时没有传参数,Bean名称默认为当前类的类名,首字母小写
- @Service(“serviceBeanId”)或@Service(value=”serviceBeanId”)使用时传参数,使用value作为Bean名字
- @Service注解使用时不传参Bean名默认为当前类名,首字母小写
- @Service注解使用时传参Bean名为参数value的值
3、@Scope注解
- @Scope作用在类上和方法上
- @Scope用来配置 spring bean 的作用域,它标识 bean 的作用域
- singleton单例模式:Spring 容器中有且只有一个Bean实例,只要Spring容器不销毁或退出,该Bean实例就会一直存活
- prototype原型模式:每次获取Bean的时候会有一个新的实例,Spring容器不能对返回Bean实例的整个生命周期负责
- request模式:request只适用于Web程序,每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,当请求结束后,该 对象的生命周期即告结束
- session模式:session只适用于Web程序,session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session 内有效
- application模式:application只适用于Web程序,全局作用域
使用示例:@Service和@Scope注解一起使用
// 单例 @Service @Scope("singleton") public class SingletonScope { public SingletonScope() { } } //原型 @Service @Scope("prototype") public class PrototypeScope { public PrototypeScope() { } }
4、@Entity
- SpringMVC中model层相当于SpringBoot中的entity层,@Entity注解在实体类(domain层)上面。
- @Table(name ="数据库表名"),这个注解也注释在实体类上,对应数据库中相应的表。
- @Id、@Column注解用于标注实体类中的字段,pk字段标注为@Id,其余@Column。
5、@Autowired、@Qualifier和@Resource
1、@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。
2、@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:
@Autowired() @Qualifier("baseDao") private BaseDao baseDao;
3、@Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定, 如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。 Java代码
@Resource(name="baseDao") private BaseDao baseDao;
推荐使用:@Resource注解在字段上,且这个注解是属于J2EE的,减少了与spring的耦合。最重要的这样代码看起就比较优雅。
6、@Component
- @Component作用在类上
- @Component注解作用域默认为singleton
- 使用注解配置和类路径扫描时,被@Component注解标注的类会被Spring扫描并注册为Bean
- @Component使用在不确定哪一个层的时候使用,可以作用在任何层次,把普通pojo实例化到spring容器
- 不推荐使用@Component注解,而应该使用它的扩展,如@Service、@Repository
7、@Bean产生一个bean的方法
@Bean明确地指示了一种方法,产生一个bean的方法,并且交给Spring容器管理。支持别名@Bean("xx-name")
8、@Order加载bean的顺序
加载bean的顺序,按优先级加载,数字越小优先级越高。
五、导入配置文件
1、@ImportResource导入xml配置文件
在Java配置文件中引入xml配置文件,可用@ImportResource
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="compactDisc" class="soundsystem.BlankDisc" c:_0="Sgt. Pepper's Lonely Hearts Club Band" c:_1="The Beatles"> <constructor-arg> <list> <value>Sgt. Pepper's Lonely Hearts Club Band</value> <value>With a Little Help from My Friends</value> <value>Lucy in the Sky with Diamonds</value> <value>Getting Better</value> <value>Fixing a Hole</value> <!-- ...other tracks omitted for brevity... --> </list> </constructor-arg> </bean> </beans>
使用:
package soundsystem; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.ImportResource; @Configuration @ImportResource("classpath:cd-config.xml") public class SoundSystemConfig { }
支持通配符:@ImportResource("classpath:*.xml")
@ImportResource({"classpath*:spring/*Context*.xml"})
2、@Import导入配置类
简介:功能类似XML配置的,用来导入配置类,可以导入带有@Configuration注解的配置类或实现了ImportSelector/ImportBeanDefinitionRegistrar,或者导入普通的POJO(Spring会将其注册成Spring Bean,导入POJO需要使用Spring 4.2以上)。多个逗号隔开。
@SpringBootApplication @Import({SmsConfig.class}) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
六、事物
1、事务说明
在Spring中,事务有两种实现方式,分别是编程式事务管理和声明式事务管理两种方式。
- 编程式事务管理: 编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。
- 声明式事务管理: 建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
声明式事务管理不需要入侵代码,通过@Transactional就可以进行事务操作,更快捷而且简单。推荐使用
2、使用示例
@Autowired OrderServiceorderService; //order操作的Service层 @ApiOperation(value = "增加OrderCustomer") @RequestMapping(value = "", method = RequestMethod.POST) @ResponseBody @Transactional public JsonBean<Order> insertOrder(@RequestParam(value = "order") String order) { try { //创建订单 Order order = orderService.insert(user.getId(),is_company,fk_want_company_id); return new JsonBean(SUCCESS, orderCustomer); } catch (ErrorCodeException e) { TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return new JsonBean(e.getErrorCode()); } }
3、常用配置
参 数 名 称 功 能 描 述
- readOnly:该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true)
- rollbackFor :该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
- rollbackForClassName :该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:指定单一异常类名称@Transactional(rollbackForClassName=”RuntimeException”)指定多个异常类名称:@Transactional(rollbackForClassName={“RuntimeException”,”Exception”})
- noRollbackFor :该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})
- noRollbackForClassName :该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:指定单一异常类名称:@Transactional(noRollbackForClassName=”RuntimeException”)指定多个异常类名称:@Transactional(noRollbackForClassName={“RuntimeException”,”Exception”})
- propagation :该属性用于设置事务的传播行为。例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
- isolation :该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置
- timeout :该属性用于设置事务的超时秒数,默认值为-1表示永不超时
4、事务属性
4.1、事务隔离级别
隔离级别是指若干个并发的事务之间的隔离程度。TransactionDefinition 接口中定义了五个表示隔离级别的常量:
- TransactionDefinition.ISOLATION_DEFAULT:这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED。
- TransactionDefinition.ISOLATION_READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读,不可重复读和幻读,因此很少使用该隔离级别。比如PostgreSQL实际上并没有此级别。
- TransactionDefinition.ISOLATION_READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。
- TransactionDefinition.ISOLATION_REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。该级别可以防止脏读和不可重复读。
- TransactionDefinition.ISOLATION_SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
4.2、事务传播行为
所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:
- TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
- TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
- TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
- TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
- TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
- TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
- TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
4.3、事务超时
所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。
默认设置为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。
4.4、事务只读属性
只读事务用于客户代码只读但不修改数据的情形,只读事务用于特定情景下的优化,比如使用Hibernate的时候。
默认为读写事务。
七、mybatis相关
1、@Mapper
作用:在接口类上添加了@Mapper,在编译之后会生成相应的接口实现类
添加位置:接口类上面
@Mapper public interface UserDAO { //代码 }
如果想要每个接口都要变成实现类,那么需要在每个接口类上加上@Mapper注解,比较麻烦,解决这个问题用@MapperScan
2、@MapperScan
作用:指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类
添加位置:是在Springboot启动类上面添加
@SpringBootApplication @MapperScan("com.winter.dao") public class SpringbootMybatisDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringbootMybatisDemoApplication.class, args); } }
添加@MapperScan(“com.winter.dao”)注解以后,com.winter.dao包下面的接口类,在编译之后都会生成相应的实现类。
2.1、使用@MapperScan注解多个包
(实际用的时候根据自己的包路径进行修改)
@SpringBootApplication @MapperScan({"com.kfit.demo","com.kfit.user"}) public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
2.2、使用@MapperScan通配符扫描多个包
(没验证过,不确定能否使用,或许需要根据自己定义的包名进行修改路径)
@SpringBootApplication @MapperScan({"com.kfit.*.mapper","org.kfit.*.mapper"}) public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }