SSM框架中注解含义及应用场景小结
发布日期:2021-10-02 10:57:24 浏览次数:30 分类:技术文章

本文共 8431 字,大约阅读时间需要 28 分钟。

先说一下什么是组件扫描

指定一个包路径,Spring会自动扫描该包及其子包所有组件类,当发现组件类定义前有特定的注解标记时,就将该组件纳入到Spring容器。等价于原有XML配置中的<bean>定义功能。

组件扫描可以替代大量XML配置的<bean>定义。

使用组件扫描,首先需要在XML配置中指定扫描类路径

<context:component-scan

      base-package = "org.example"/>

上面配置,容器实例化时会自动扫描org.example包及其子包下所有组件类

指定扫描类路径后,并不是该路径下所有组件类都扫描到Spring容器的,只有在组件类定义前面有以下注解标记时,才会扫描到Spring容器。

@Component:通用注解;@Name:通用注解;@Repository:持久化层组件注解

@Service:业务层组件注解;@Controller:控制层组件注解

当一个组件在扫描过程中被检测到时,会生成一个默认id值,默认id为小写开头的类名。也可以在注解标记中自定义id。下面两个组件id名字分别是oracleUserDao和loginService

@Repository

public class OracleUserDao implements UserDao{

  //.....

}

@Service("loginService")

public class UserService{

  //....

}

通常受Spring管理的组件,默认的作用域是“singleton”。如果需要其他作用域可以使用@Scope注解,只要在注解中提供作用域的名称即可。

@Scope("prototype")

@Repository

public class OracleUserDao implements EmpDao{

  //...

}

@PostConstruct和@PreDestroy注解标记分别用于指定初始化和销毁回调方法,使用示例:

public class ExampleBean{

  @PostConstruct

  public void init(){

    //初始化回调方法

  }

  @PreDestroy

  public void destroy(){

  //销毁回调方法

  }

}

具有依赖关系的Bean对象,利用下面任何一种注解都可以实现关系注入:

@Resource

@Autowired/@Qualifier

@Inject/@Named

 

@Resource注解标记可以用在字段定义或setter方法定义前面,默认首先按名称匹配注入,然后类型匹配注入:

public class UserService{

  //@Resource

  private UserDao userDao;

  @Resource

  public void setUserDao(UserDao dao){

    this.userDao = dao;

  }

}

当遇到多个匹配Bean时注入会发生错误,可以显示指定名称,例如@Resource(name = "empDao1")

@Autowired注解标记也可以用在字段定义或setter方法定义前面,默认按类型匹配注入:

public class UserService{

  //@Autowired

  private UserDao userDao;

  @Autowired

  public void setUserDao(UserDao dao){

    this.userDao = dao;

  }

}

@Autowired当遇到多个匹配Bean时注入会发生错误,可以使用下面方法指定名称:

public class UserService{

  //@Autowired

  //@Qualifiter("mysqlUserDao")

  private UserDao userDao;

  @Autowired

  public void setUserDao(@Qualifiter("mysqlUserDao")  userDao dao){

    this.userDao = dao;

  }

}

@Inject注解标记是Spring3.0开始增添的对JSR-330标准的支持,使用前需要添加JSR-330的jar包,使用方法与@Autowired相似,具体如:

public class UserService{

  //@Inject

  private UserDao  userDao;

  @Inject

  public void setUserDao(UserDao dao){

    this.userDao = dao;

  }

}

@Inject当遇到多个匹配Bean时注入会发生错误,可以使用@Named指定名称限定,使用方法为:

public class UserService{

  private UserDao userDao;

  @Inject

  public void setUserDao(@Named("mysqlUserDao")  UserDao dao){

    this.userDao = dao;

  }

}

 

@Value注解可以注入Spring表达式值,使用方法:

首先在XML配置中指定要注入的properties文件

<util:properties id = "jdbcProps"  location = "classpath:db.properties"/>

然后在setter方法前使用@Value注解

public class JDBCDataSource{

  @Value("#{jdbcProps.url}")

  private String url;

  @Value("#{jdbcProps.driver}")

  public void setUrl(String driver){

    try{Class.forName(driver)}catch(.....)...

  }

}

 

RequestMapping注解应用

@RequestMapping可以用在类定义和方法定义上

@RequestMapping标明这个类或者方法与哪一个客户请求对应

@RequestMapping可以定义在Controller类前和处理方法前,主要用于指定Controller的方法处理哪些请求

@Controller

@RequestMapping("/demo01")

public class Controller{

  @RequestMapping("/hello")

  public String execute()throws Exception{

    return "hello";

  }

}

开启@RequestMapping注解映射,需要在Spring的XML配置文件中定义RequestMappingHandlerMapping(类定义前)和RequestMappingHandlerAdapter(方法定义前)两个bean组件

示例:

<bean 

class ="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

<bean

class = "org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

从Spring3.2版本开始可以使用下面XML配置简化RequestMappingHandlerMapping和RequestMappingHandlerAdapter定义:

<mvc:annotation-driven/>

 

Controller注解应用

推荐使用@Controller注解声明Controller组件,这样可以使得Controller定义更加灵活,可以不用实现Controller接口,请求处理的方法也可以灵活定义

@Controller

@RequestMapping("/demo01")

public classs Controller{

 @RequestMapping("/hello")

  public String execute()throws Exception{

    return "hello";

  }

}

为了使@Controller注解生效,需要在Spring的XML配置文件中开启组件扫描定义,并指定Controller组件所在包

<context:component-scan  base-package = "com.controller"/>

 

接受请求参数值

Spring MVC Web请求提交数据到控制器有下面几种方法:

使用 HttpServletRequest获取

使用@RequestParam注解

使用自动机制封装成Bean对象

 

使用@RequestParam注解:

Spring会自动将表单参数注入到方法参数(名称一致)

使用@RequestParam注解,映射不一致的名称

优点参数类型会自动转换,但可能出现类型转换异常

@RequestMapping("/login-action.form")

public String checkLogin(String name,@RequestParam("pwd")String password,HttpServletRequest req){

  System.out.println(name);

  System.out.println(password);

  User user = userService.login(name,password);

    //处理过程

  return "success";

 

使用@ModelAttribute注解是当Controller组件处理后,需要向JSP传值用此方法。

(引出:向JSP页面传值也可以直接使用HttpServletRequest和Session;ModeAndView对象;ModelMap参数对象等)

示例:

在Controller方法的参数部分或Bean属性方法上使用。

@RequestMapping("login-action.from")

public String checkLogin(@ModelAttribute("user")User user){

  //处理过程

  return "success";

}

@ModelAttribute("name")

public String getName(){

  return name;

}

(@ModelAttribute数据会利用HttpServletRequest的Attribute传递到JSP页面中)

@ExceptionHandler注解

@ExceptionHandler注解提供了Spring MVC处理异常的方法

(引出:Spring MVC处理异常的方法有三种:使用Spring MVC提供的简单异常处理器(SimpleMappingExceptionResolver);实现HandlerExceptionResolver接口自定义异常处理器;使用 @ExceptionHandler注解实现异常处理)

@ExceptionHandler注解使用方法:

public class BaseController{

  @ExceptionHandler

  public String execute(HttpServletRequest req,Exception e){

    req.setAttribute("e",e);

    //可根据异常类型不同返回不同视图名

    return "error";

  }

}

(适合局部处理有“处理过程”的异常)

然后其他的Controller继承BaseController类即可

 

@ResponseBody注解(在Spring MVC中,此注解与JSON响应相关)

在控制器方法上使用 @ResponseBody 注解, 就可以自动的将控制器的返回值(JavaBean)转换为JSON发送到客户端.

@ResponseBody注解主要用于Controller组件的处理方法前,使用方法为:

引入jackson开发包,后面示例用的是jackson-annotations-2.4.1.jar,jackson-core-2.4.1.jar,jackson-databind-2.4.1.jar

在Spring配置文件中定义<mvc:annotation-driven/>,开启对@ResponseBody应用的支持

在Controller处理方法前定义@ResponseBody注解

示例:

使用@ResponseBody,返回单个值:

@RequestMapping("/test1")

@ResponseBody

public boolean f1(){


  //业务处理代码

  return true;

}

使用@ResponseBody返回多个值:

@RequestMapping("/test2")

@ResponseBody

public Map<String,Object>f2(){

  Map<String,Object> m = new HashMap<String,Object>)();

  m.put("id",1);

  m.put("name","Tom");

  return m;

}

使用@ResponseBody返回List结果:

@RequestMapping("/test3")

@ResponseBody

public List<String>f3(){


  List<String> list = new ArrayList<String>();

  list.add("java");

  list.add("php");

  list.add("ui");

  return list;

}

使用@ResponseBody返回对象结果:

@RequestMapping("/test4")

@ResponseBody

public Object f4(){

  Object obj = new Object();

  return obj;

}

使用@ResponseBody返回对象集合结果:

@RequestMapping("/test5")

@ResponseBody

public Object f5(){

  Emp e1 = new Emp();

  e1.setId(1);

  e1.setName("张三");

 

  Emp e2 = new Emp();

  e2.setId(2);

  e2.setName("李四");

 

  List<Emp> list = new ArrayList<Emp>();

  list.add(e1);

  ;ist.add(e2);

  return list;

}

 

注解实现AOP

开发步骤:

创建方面组件:

创建一个类,充当方面组件,实现通用业务逻辑。

声明方面组件:

在applicationContext.xml中开启AOP注解扫描:

<aop:aspectj-autoproxy proxy-target-class = "true"/>;

使用@Component注解标识这个类,将其声明为组件。

使用@Aspect注解标识这个类,将其声明为方面组件。

使用方面组件:

在组件的方法上,使用注解将方面组件作用到目标组件的方法上,并设置通知类型以确认方面组件调用的时机。

 

使用前置通知,在方面组件方法上增加注解:

@Before("within(controller..*)")

public void log(){

}

后置通知、最终通知使用方法与前置通知一致,只需要将注解改为@AfterReturning、@After即可。

环绕通知,在方面组件方法上增加注解:

@Around("within(controller..*)")

public Object log(ProceedingJoinPoint p) throws Throwable{

  //此处代码在目标组件前执行

  Object obj = p.proceed();//执行目标组件方法

  //此处代码在目标组件后执行

  return obj;

}

使用异常通知,在方面组件方法上增加注解:

@AfterThrowing(pointcut = "within(controller..*)",throwing = "e")

public void log(Exception e){

}

 

 

@Transactional注解

此注解实现声明式事务,步骤如下:

在applicationContext.xml中声明事务组件,开始事务注解扫描,示例为:

<!-- 声明事务管理组件 -->

<bean id = "txManager"

  class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">

      <property name = "dataSource"  ref = "ds"/>

</bean>

<!-- 开启事务注解扫描 -->

<tx:annotation-driven transaction-manager = "txManager"  proxy-target-class = "true"/>

transaction-manager指定的事务管理器txManager,需要根据数据库访问技术不同选择不同的实现。例如JDBC、Mybatis技术选用DataSourceTransactionManager,而Hibernate技术则选用HibernateTransactionManager.

 

使用 @Transactional注解声明事务,使用方法为:

 @Transactional

public class DefaultFooService implements FooService{

  // @Transactional

  public void insertFoo(Foo foo){...}

  public void updateFoo(Foo foo){...}

 @Transactional注解标记可以用在类定义和方法定义前,方法的事务设置将优先于类级别注解的事务设置。

 @Transactional注解标记有以下属性,在使用时可以根据需要做特殊设定:

- propagation:设置事务传播

- isolation:设置事务隔离级别

- readOnly:设置为只读,还是可读写

- rollbackFor:设置遇到哪些异常必须回滚

- noRollbackFor:设置遇到哪些异常不回滚

 

@Transactional注解属性默认设置如下:

事务传播设置是:PROPAGATION_REQUIRED

事务隔离级别是:ISOLATION_DEFAULT

事务是读/写

事务超时默认是依赖于事务系统的,或者事务超时没有被支持

任何RuntimeException将触发事务回滚,但是任何Checked Exception将不触发事务回滚

 

 

@PathVariable应用

@PathVariable作用是将URI请求模板中的变量解析出来,映射到处理方法的参数上,示例为:

@RequestMapping(value = "/emp/{id}",method = requestMethod.GET)

public String execute(@PathVariable("id") int id){

  //查询操作处理

  return " ";

}

上述URI请求模板匹配/emp/1、emp/2等格式请求

转载了别人的,觉得很详细了,希望对你们有用!

转载地址:https://blog.csdn.net/JiangYunWen34/article/details/79799206 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:服务端签名后直传(上传文件到oss)
下一篇:SpringMVC上传文件的三种方式

发表评论

最新留言

不错!
[***.144.177.141]2024年03月26日 08时28分19秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

echart实现3d地图_orbslam_2生成稀疏点云地图的保存与加载的实现 邹鹏程 2019.9.15... 2019-04-21
bash 不是内部或外部命令_python学习笔记6-pip命令不是内部命令问题 2019-04-21
管道的另一端上无任何进程。_别被忽悠入坑!信号贴贴上就能信号满格?对手机信号无任何改善... 2019-04-21
mysql无法写数据库_求助,为何我的数据不能写入数据库 2019-04-21
ssh 两个mysql数据库_ssh连接两个数据库(转) 2019-04-21
mysql 双向链表_23张图!万字详解「链表」,从小白到大佬! 2019-04-21
mysql 常量命名规则_详解Java编程规约(命名风格、常量定义、代码格式) 2019-04-21
pomelo mysql_全文索引 - Pomelo.EFCore.MySql 2019-04-21
如何打开git命令窗口_win10系统如何将右键菜单中“在此处打开powershell窗口”调整为“在此处打开命令窗口”?... 2019-04-21
rtsp 华为_华为多实例生成树RSTP配置详解 2019-04-21
ewb交通灯报告和文件_基于ewb平台的交通灯电路设计.doc 2019-04-21
mysql中$使用_在MySQL中使用序列的简单教程 2019-04-21
mysql alter auto increment_将MySQL列更改为AUTO_INCREMENT 2019-04-21
mysql+err+1067_MySQL 5.7 Invalid default value for 'CREATE_TIME'报错的解决方法 2019-04-21
程序中mysql添加用户_MySQL添加用户的两种方法 2019-04-21
简述mysql安装过程_mysql安装的过程 2019-04-21
后端接口重定向_不用再等后端的接口啦!这个开源项目花 2 分钟就能模拟出后端接口... 2019-04-21
学mysql需要英语水平多高_大学英语专业挂科率高吗 2019-04-21
mysql group by实现_SQL数据分析之 group by 的实现原理 2019-04-21
mysql数据库大小如何查看器_如何用SQL命令查看Mysql数据库大小 2019-04-21