【SSM】SSM常用注解总结

SSM常用注解总结

@Param

Dao接口中方法定义,多个参数

User findByCondition(@Param("id") Integer id,@Param("username") String username);

lombok注解

@Data //get,set,toString,Hashcode,equals等方法

@NoArgsConstructor //空参构造

@AllArgsConstructor //带参构造

public class Account {

private Integer id;

private String name;

private Double money;

}

@Component@Controller,@Service ,@Repository

上述4个注解都是加到类上的。

他们都可以起到类似bean标签的作用。可以把加了该注解类的对象放入Spring容器中。

实际再使用时选择任意一个都可以。但是后3个注解是语义化注解。

如果是Service类要求使用@Service。

如果是Dao类要求使用@Repository

如果是Controllerl类要求使用@Controller

如果是其他类可以使用@Component

@Repository("userDao")

public class UserDaoImpl implements UserDao {

public void show() {

System.out.println("查询数据库,展示查询到的数据");

}

}

@Data

@NoArgsConstructor

@AllArgsConstructor

@Component("phone")

public class Phone {

private double price;

private String name;

private String password;

private String path;

}

@Service("userService")

@Data

@NoArgsConstructor

@AllArgsConstructor

public class UserServiceImpl implements UserService {

private UserDao userDao;

private int num;

private String str;

public void show() {

userDao.show();

}

}

@Value

简单类型注入,主要用于String,Integer等可以直接赋值的属性注入。不依赖setter方法,支持SpEL表达式。

@Service("userService")

@Data

@NoArgsConstructor

@AllArgsConstructor

public class UserServiceImpl implements UserService {

private UserDao userDao;

@Value("199")

private int num;

@Value("若风")

private String str;

@Value("#{19+3}")

private Integer age;

public void show() {

userDao.show();

}

}

@AutoWired

引用数据类型注入,一般用于下面两种,注入Dao接口和service接口

@Service

public class UserServiceImpl implements UserService {

@Autowired

private UserDao userDao;

@Controller

public class UserController {

@Autowired

private UserService userService;

required属性代表这个属性是否是必须的,默认值为true。

如果是true的话Spring容器中如果找不到相同类型的对象完成属性注入就会出现异常。

@Autowired(required = false)

private UserService userService;

如果改为false,就是找不到也无所谓,不报错,但是不会赋值,就是null

@Qualifier

如果相同类型的bean在容器中有多个时,单独使用@AutoWired就不能满足要求,这时候可以再加上@Qualifier来指定bean的名字从容器中获取bean注入。

@Autowired

@Qualifier("userDao2")

private UserDao userDao;

注意:该直接不能单独使用。单独使用没有作用

@Configuration

标注在类上,表示当前类是一个配置类。我们可以用注解类来完全替换掉xml配置文件。

@Configuration

public class ApplicationConfig {

}

@ComponentScan

可以用来代替context:component-scan标签来配置组件扫描。basePackages属性来指定要扫描的包。

注意要加在配置类上。

@Configuration

@ComponentScan(basePackages = "com.sangeng")//指定要扫描的包

public class ApplicationConfig {

}

@Bean

和@component@Service@Repository一样 都是代替标签放到spring容器中的,但是@Bean主要是用来导入第三方类的 比如DruidDataSource类

使用:定义一个方法,在方法中创建对应的对象并且作为返回值返回。然后在方法上加上@Bean注解,注解的value属性来设置bean的名称。

@Configuration

@ComponentScan(basePackages = "com.sangeng")

public class ApplicationConfig {

@Bean("dataSource")

public DruidDataSource getDataSource(){

DruidDataSource druidDataSource = new DruidDataSource();

druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");

druidDataSource.setUsername("root");

druidDataSource.setUrl("jdbc:mysql://localhost:3306/mybatis_db");

druidDataSource.setPassword("root");

return druidDataSource;

}

}

注意事项:如果同一种类型的对象在容器中只有一个,我们可以不设置bean的名称

@Configuration

@ComponentScan(basePackages = "com.sangeng")

public class ApplicationConfig {

@Bean

public DruidDataSource getDataSource(){

DruidDataSource druidDataSource = new DruidDataSource();

druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");

druidDataSource.setUsername("root");

druidDataSource.setUrl("jdbc:mysql://localhost:3306/mybatis_db");

druidDataSource.setPassword("root");

return druidDataSource;

}

}

@PropertySource

可以用来代替context:property-placeholder,让Spring读取指定的properties文件。然后可以使用@Value来获取读取到的值。

使用:在配置类上加@PropertySource注解,注解的value属性来设置properties文件的路径。

然后在配置类中定义成员变量。在成员变量上使用@Value注解来获取读到的值并给对应的成员变量赋值。

@Configuration

@ComponentScan(basePackages = "com.sangeng")

@PropertySource("jdbc.properties")

public class ApplicationConfig {

@Value("${jdbc.driver}")

private String driverClassName;

@Value("${jdbc.url}")

private String url;

@Value("${jdbc.username}")

private String username;

@Value("${jdbc.password}")

private String password;

}

注意事项:使用@Value获取读到的properties文件中的值时使用的是${key},而不是#{key}。

@Aspect切面类

@Pointcut切点

@Component

@Aspect

public class MyAspect {

// 用Pointcut注解中的属性来指定对哪些方法进行增强

@Pointcut("execution(* com.sangeng.service.*.*(..))")

public void pt(){}

/*

用@Before注解来指定该方法中是增强的代码,并且是在被增强方法执行前执行的

@Before的属性写上加了@Pointcut注解的方法: 方法名()

*/

@Before("pt()")

public void methodbefore(){

System.out.println("方法被调用了");

}

}

@annotation

我们也可以在要增强的方法上加上注解。然后使用@annotation来表示对加了什么注解的方法进行增强。

写法:@annotation(注解的全类名)

例如:

定义注解如下

@Target({ElementType.METHOD})//该注解可以加在方法上

@Retention(RetentionPolicy.RUNTIME)

public @interface InvokeLog {

}

给需要增强的方法增加自定义注解

@Service

public class PhoneService {

@InvokeLog

public void deleteAll(){

System.out.println("PhoneService中deleteAll的核心代码");

}

}

切面类中使用@annotation来确定要增强的方法

@Component

@Aspect

public class MyAspect {

// 用Pointcut注解中的属性来指定对哪些方法进行增强

@Pointcut("@annotation(com.sangeng.aspect.InvokeLog)")

public void pt(){}

@Before("pt()")

public void methodbefore(){

System.out.println("方法被调用了");

}

}

通知分类

@Before:前置通知,在目标方法执行前执行

@AfterReturning: 返回后通知,在目标方法执行后执行,如果出现异常不会执行

@After:后置通知,在目标方法之后执行,无论是否出现异常都会执行

@AfterThrowing:异常通知,在目标方法抛出异常后执行

@Around:环绕通知,围绕着目标方法执行

伪代码方便理解

public Object test() {

before();//@Before 前置通知

try {

Object ret = 目标方法();//目标方法调用

afterReturing();//@AfterReturning 返回后通知

} catch (Throwable throwable) {

throwable.printStackTrace();

afterThrowing();//@AfterThrowing 异常通知通知

}finally {

after();//@After 后置通知

}

return ret;

}

环绕通知

@Around("pt()")

public void around(ProceedingJoinPoint pjp){

System.out.println("目标方法前");

try {

pjp.proceed();//目标方法执行

System.out.println("目标方法后");

} catch (Throwable throwable) {

throwable.printStackTrace();

System.out.println("目标方法出现异常");

}finally {

System.out.println("finally中进行增强");

}

}

@Order

多切面顺序问题

在实际项目中我们可能会存在配置了多个切面的情况。这种情况下我们很可能需要控制切面的顺序。

我们在默认情况下Spring有它自己的排序规则。(按照类名排序)

如果是注解方式配置的AOP可以在切面类上加**@Order注解来控制顺序。@Order中的属性越小优先级越高。**

@Component

@Aspect

@Order(2)

public class APrintLogAspect {

//省略无关代码

}

@Component

@Aspect

@Order(1)

public class CryptAspect {

//省略无关代码

}

先使用CryptAspect里面的增强,再使用APrintLogAspect里的增强

@RunWith

@ContextConfiguration

@test

测试类中

@RunWith(SpringJUnit4ClassRunner.class)//让测试运行与Spring测试环境

@ContextConfiguration(locations = "classpath:applicationContext.xml")设置Spring配置文件或者配置类

public class SpringTest {

@Autowired

private AccountService accountService;

@Autowired

private TestServiceImpl testServiceImpl;

@Test

public void testTransfer() {

accountService.transfer(2,1,20.0);

}

@Test

public void testPropagation(){

testServiceImpl.test();

}

}

@Transactional

对service类中方法进行事务控制,底层是AOP增强

@Service

public class UserServiceImpl implements UserService {

@Autowired

private UserDao userDao;

@Transactional

@Override

public void test() {

userDao.insertUser(new User(null,"test1",11,"aa"));

System.out.println(1/0);//除0异常

userDao.insertUser(new User(null,"test2",12,"bb"));

}

传播行为参数

属性值行为REQUIRED(必须要有)外层方法有事务,内层方法就加入。外层没有,内层就新建REQUIRES_NEW(必须要有新事务)外层方法有事务,内层方法新建。外层没有,内层也新建SUPPORTS(支持有)外层方法有事务,内层方法就加入。外层没有,内层就也没有NOT_SUPPORTED(支持没有)外层方法有事务,内层方法没有。外层没有,内层也没有MANDATORY(强制要求外层有)外层方法有事务,内层方法加入。外层没有。内层就报错NEVER(绝不允许有)外层方法有事务,内层方法就报错。外层没有。内层就也没有

@Transactional(propagation = Propagation.REQUIRES_NEW)

@Override

public void test() {

userDao.insertUser(new User(null,"test1",11,"aa"));

System.out.println(1/0);//除0异常

userDao.insertUser(new User(null,"test2",12,"bb"));

}

隔离级别参数

Isolation.DEFAULT 使用数据库默认隔离级别

Isolation.READ_UNCOMMITTED 读未提交

Isolation.READ_COMMITTED 读已提交

Isolation.REPEATABLE_READ 可重复读

Isolation.SERIALIZABLE 序列化

@Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.READ_COMMITTED)

@Override

public void test() {

userDao.insertUser(new User(null,"test1",11,"aa"));

System.out.println(1/0);//除0异常

userDao.insertUser(new User(null,"test2",12,"bb"));

}

只读readOnly

如果事务中的操作都是读操作,没涉及到对数据的写操作可以设置readOnly为true。这样可以提高效率。

@Transactional(readOnly = true)

public void log() {

System.out.println("打印日志");

int i = 1/0;

}

@RequestMapping

设置请求规则

该注解可以加到方法上或者是类上,我们期望让请求的资源路径为**/test/testPath的请求能够被testPath**方法处理则可以写如下代码

@Controller

@RequestMapping("/test")

public class TestController {

@RequestMapping("/testPath")

public String testPath(){

return "/success.jsp";

}

}

指定请求方式

@PostMapping

@GetMapping

@PutMapping

@DeleteMapping

@PathVariable

从请求路径获取RestFul风格的请求参数,不加默认获取QueryString格式参数(需要字段名一致)

获取多个参数,写多个@PathVariable

@GetMapping("/user/{id}")

public ResponseResult findById(@PathVariable("id") Integer id) {//从请求路径获取id

User user = userService.findById(id);

if(user == null) {

return new ResponseResult(500,"没有该用户");

}

return new ResponseResult(200,"操作成功",user);

}

@RequestParam

从请求路径获取QueryString格式参数,如果方法参数名和请求参数名不一致,我们就需要加上**@RequestParam**注解

@RequestMapping("/testRquestParam")

public String testRquestParam(@RequestParam("id") Integer uid,@RequestParam("name") String name, @RequestParam("likes")String[] likes){

System.out.println("testRquestParam");

System.out.println(uid);

System.out.println(name);

System.out.println(Arrays.toString(likes));

return "/success.jsp";

}

@RequestBody

从请求体中获取json格式的数据

@PostMapping("/user")

public ResponseResult insertUser(@RequestBody User user) {//从请求体中获取user(json格式)

userService.insertUser(user);

return new ResponseResult(200,"操作成功");

}

相关注解其他参数属性

required

代表是否必须,默认值为true也就是必须要有对应的参数。如果没有就会报错。

如果对应的参数可传可不传则可以把去设置为fasle

例如:

@RequestMapping("/testRquestParam")

public String testRquestParam(@RequestParam(value = "id",required = false) Integer uid,@RequestParam("name") String name, @RequestParam("likes")String[] likes){

System.out.println("testRquestParam");

System.out.println(uid);

System.out.println(name);

System.out.println(Arrays.toString(likes));

return "/success.jsp";

}

defaultValue

@RequestParam特有属性

如果对应的参数没有,我们可以用defaultValue属性设置默认值。

例如:

@RequestMapping("/testRquestParam")

public String testRquestParam(@RequestParam(value = "id",required = false,defaultValue = "777") Integer uid,@RequestParam("name") String name, @RequestParam("likes")String[] likes){

System.out.println("testRquestParam");

System.out.println(uid);

System.out.println(name);

System.out.println(Arrays.toString(likes));

return "/success.jsp";

}

@ResponseBody

可以加到方法或者类上

表示方法的返回值都会被自动转化为json格式放到响应体中返回给客户端

@Controller

@RequestMapping("/response")

public class ResponseController {

@GetMapping("/user/{id}")

@ResponseBody //这方法的返回值放入响应体中

public User testResponse(@PathVariable Integer id){

User user = new User(id,null,null,null);

return user;

}

}

一般和@Controller连用,变成**@RestController**

@RestController//这类中所有方法的返回值都会放到响应体中

public class UserController {

@Autowired

private UserService userService;

@DateTimeFormat

指定字符串的格式

请求路径中传递yyyy-MM-dd这种格式的字符串会被解析为日期类

@RequestMapping("/testDateConverter")

public String testDateConverter(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){

System.out.println("testDateConverter");

System.out.println(birthday);

return "/success.jsp";

}

@RequestHeader

在方法中定义一个参数,参数前加上**@RequestHeader**注解,知道要获取的请求头名即可获取对应请求头的值。

想要获取 device-type 这个请求头则可以按照如下方式定义方法。

@Controller

public class RequestResponseController {

@RequestMapping("/getHeader")

public String getHeader(@RequestHeader(value = "device-type") String deviceType){

System.out.println(deviceType);

return "test";

}

}

@CookieValue

在方法中定义一个参数,参数前加上**@CookieValue** 注解,知道要获取的cookie名即可获取对应cookie的值。

想要获取 JSESSIONID 的cookie值。则可以按照如下方式定义方法。

@Controller

public class RequestResponseController {

@RequestMapping("/getCookie")

public String getCookie(@CookieValue("JSESSIONID") String sessionId){

System.out.println(sessionId);

return "test";

}

}

@ControllerAdvice

@ExceptionHandler

统一异常处理,我们在实际项目中Dao层和Service层的异常都会被抛到Controller层

创建类加上**@ControllerAdvice注解进行标识,自定义异常处理方法使用@ExceptionHandler**标识可以处理的异常。

@Component

@ControllerAdvice

public class MyControllerAdvice {

@ExceptionHandler({NullPointerException.class,ArithmeticException.class})

public ModelAndView handlerException(Exception ex){

//如果出现了相关的异常,就会调用该方法

String msg = ex.getMessage();

ModelAndView modelAndView = new ModelAndView();

//把异常信息存入域中

modelAndView.addObject("msg",msg);

//跳转到error.jsp

modelAndView.setViewName("/WEB-INF/page/error.jsp");

return modelAndView;

}

}

@JsonInclude

一般在自定义返回到响应体的Result类中使用

//某个属性的值不为null才会转换成json

@JsonInclude(JsonInclude.Include.NON_NULL)

//任何接口都会返回一个ResponseResult对象,统一格式

public class ResponseResult {

}

友情链接: