先理解核心概念:什么是注解(annotation)?
类比:注解就像代码里的“便利贴”,用来告诉 spring 框架:“这个类/方法/变量有什么特殊用途”。
作用:简化配置,让框架自动帮你处理一些事情(比如创建对象、管理依赖、处理请求等)。
第一部分:ioc(控制反转)和 di(依赖注入)
核心思想:把对象的创建和管理交给 spring 容器,而不是自己手动 new
对象。
注解 | 说明 | 示例 |
---|---|---|
@component | 通用组件标记,被扫描的类会纳入 spring 容器管理 | @component public class mycomponent { ... } |
@service | 标记服务层组件,属于@component 的特化形式 | @service public class userservice { ... } |
@repository | 标记数据访问层组件(dao层),具有数据库异常转译功能 | @repository public class userdao { ... } |
@controller | 标记控制器组件(web层) | @controller public class usercontroller { ... } |
@autowired | 自动注入依赖,默认按类型匹配 | @autowired private userservice userservice; |
@qualifier | 按名称指定注入的 bean | @autowired @qualifier("userserviceimpla") private userservice service; |
@primary | 标记首选的 bean(存在多个同类型 bean 时优先注入) | @bean @primary public datasource primarydatasource() { ... } |
@scope | 定义 bean 的作用域(singleton/prototype等) | @component @scope("prototype") public class myprototypebean { ... } |
1. @component
作用:告诉 spring:“这个类交给你管理,我需要的时候找你要实例”。
代码示例:
@component // 贴上这个标签,spring 就会自动创建 mycomponent 的实例(bean) public class mycomponent { public void hello() { system.out.println("hello from mycomponent!"); } }
使用场景:通用的工具类、第三方库的适配类等。
2. @service, @repository, @controller
本质:它们都是 @component
的“马甲”,用途相同,只是名字不同,为了代码可读性。
@service
:标记业务逻辑层(如处理用户注册、订单支付)。@repository
:标记数据访问层(如操作数据库)。@controller
:标记 web 控制器(处理 http 请求)。
代码对比:
@service public class userservice { // 业务逻辑层 public void registeruser(string name) { ... } } @repository public class userdao { // 数据访问层 public user finduserbyid(long id) { ... } } @controller public class usercontroller { // 处理 http 请求 @getmapping("/users") public string listusers() { ... } }
3. @autowired
作用:让 spring 自动帮你“注入”依赖的 bean(类似找人借东西,不用自己造)。
代码示例:
@service public class userservice { @autowired // spring 会自动找一个 userdao 的 bean 注入到这里 private userdao userdao; public user finduser(long id) { return userdao.finduserbyid(id); // 直接使用 userdao,不需要 new userdao() } }
原理:spring 会在容器中查找匹配类型的 bean,自动赋值给 userdao
。
4. @qualifier
问题场景:如果有多个同类型的 bean,spring 不知道注入哪一个。
解决:用 @qualifier
指定 bean 的名字。
代码示例:
// 定义两个数据源 @component("mysqldatasource") public class mysqldatasource implements datasource { ... } @component("postgresdatasource") public class postgresdatasource implements datasource { ... } // 使用时指定名称 @service public class dataservice { @autowired @qualifier("mysqldatasource") // 明确告诉 spring 注入名为 "mysqldatasource" 的 bean private datasource datasource; }
第二部分:spring mvc(处理 http 请求)
注解 | 说明 | 示例 |
---|---|---|
@restcontroller | 组合注解(@controller + @responsebody ),用于 rest api | @restcontroller public class apicontroller { ... } |
@requestmapping | 映射 http 请求路径,可指定 method | @requestmapping(value="/users", method=requestmethod.get) |
@getmapping | 简化 get 请求映射(同理有@postmapping 、@putmapping 等) | @getmapping("/{id}") public user getuser(@pathvariable long id) |
@pathvariable | 绑定 url 路径中的变量 | @getmapping("/users/{id}") public user getbyid(@pathvariable long id) |
@requestparam | 绑定请求参数(支持默认值、是否必传等) | @getmapping("/search") public list<user> search(@requestparam(defaultvalue = "") string keyword) |
@requestbody | 将请求体内容反序列化为 java 对象(如 json) | @postmapping public user create(@requestbody user user) { ... } |
@responsebody | 将方法返回值序列化为响应体(如 json) | 已内置在@restcontroller 中 |
@exceptionhandler | 处理控制器内的特定异常 | @exceptionhandler(usernotfoundexception.class) public responseentity<string> handleexception() { ... } |
@crossorigin | 允许跨域请求 | @crossorigin(origins = "http://example.com") |
1. @restcontroller vs @controller
@controller
:传统 mvc 控制器,返回视图(如 jsp 页面)。@restcontroller
:专门用于 rest api,直接返回 json 数据(内部包含@responsebody
)。
代码对比:
// 传统 controller(返回视图名,由模板引擎渲染) @controller public class oldcontroller { @getmapping("/hello") public string hello() { return "hello-page"; // 对应 src/main/resources/templates/hello-page.html } } // rest controller(返回 json) @restcontroller public class apicontroller { @getmapping("/user") public user getuser() { return new user(1, "alice"); // 自动转换为 json:{ "id": 1, "name": "alice" } } }
2. @getmapping / @postmapping
作用:简化 http 请求映射,替代 @requestmapping(method=requestmethod.get)
。
代码示例:
@restcontroller public class usercontroller { // 处理 get 请求:http://localhost:8080/users @getmapping("/users") public list<user> listusers() { return userservice.getallusers(); } // 处理 post 请求:http://localhost:8080/users @postmapping("/users") public user createuser(@requestbody user user) { // @requestbody 表示接收 json 数据 return userservice.saveuser(user); } }
3. @pathvariable 和 @requestparam
@pathvariable
:从 url 路径中获取变量(如/users/123
中的123
)。@requestparam
:从 url 参数中获取值(如/search?keyword=java
中的keyword
)。
代码示例:
@getmapping("/users/{id}") // url 模板:{id} 是占位符 public user getuserbyid(@pathvariable long id) { // 获取路径中的 id return userservice.findbyid(id); } @getmapping("/search") public list<user> searchusers(@requestparam string keyword) { // 获取参数 ?keyword=xxx return userservice.search(keyword); }
第三部分:配置相关注解
注解 | 说明 | 示例 |
---|---|---|
@configuration | 标记类为配置类(替代 xml 配置文件) | @configuration public class appconfig { ... } |
@bean | 声明方法返回的对象作为 bean 加入容器 | @bean public datasource datasource() { return new hikaridatasource(); } |
@value | 注入配置文件中的值 | @value("${db.url}") private string dburl; |
@propertysource | 加载指定 properties 文件 | @configuration @propertysource("classpath:custom.properties") |
@configurationproperties | 批量绑定配置文件属性到对象(需配合@enableconfigurationproperties ) | @component @configurationproperties(prefix="app") public class appconfig { private string name; ... } |
@profile | 指定 bean 生效的环境 | @bean @profile("dev") public datasource devdatasource() { ... } |
1. @configuration 和 @bean
作用:替代 xml 配置文件,手动定义 bean。
代码示例:
@configuration // 告诉 spring:“这是一个配置类” public class appconfig { @bean // 这个方法返回的对象会被 spring 管理 public datasource datasource() { return new hikaridatasource(); // 手动创建一个数据源 } }
2. @value
作用:从配置文件(如 application.properties
)中读取值。
示例:
# application.properties app.name=my awesome app database.url=jdbc:mysql://localhost:3306/mydb
@component public class appconfig { @value("${app.name}") // 注入 app.name 的值 private string appname; @value("${database.url}") // 注入数据库 url private string dburl; }
第四部分:spring boot 核心注解
注解 | 说明 | 示例 |
---|---|---|
@springbootapplication | 启动类注解(包含@configuration +@enableautoconfiguration +@componentscan ) | @springbootapplication public class myapp { public static void main(string[] args) { springapplication.run(myapp.class, args); } } |
@enableautoconfiguration | 启用自动配置机制(通常已包含在@springbootapplication 中) | 显式使用:@springbootapplication @enableautoconfiguration |
@conditionalonproperty | 根据配置属性条件化创建 bean | @bean @conditionalonproperty(name="feature.enabled", havingvalue="true") public featurebean featurebean() { ... } |
作用:标记启动类,包含三个核心功能:
@configuration
:这是一个配置类。@enableautoconfiguration
:开启自动配置(如自动配置数据库连接池)。@componentscan
:自动扫描当前包及子包下的组件(@component
,@service
等)。
代码示例:
@springbootapplication // 一切从这里开始 public class myapplication { public static void main(string[] args) { springapplication.run(myapplication.class, args); // 启动 spring boot 应用 } }
第五部分:数据库和事务
注解 | 说明 | 示例 |
---|---|---|
@transactional | 声明事务管理(可加在类或方法上) | @transactional public void updateuser(user user) { ... } |
@entity | jpa 实体类标记 | @entity public class user { @id private long id; ... } |
@jparepository | spring data jpa 的仓库接口 | public interface userrepository extends jparepository<user, long> { ... } |
1. @entity 和 @id
作用:标记 jpa 实体类(对应数据库表)和主键字段。
代码示例:
@entity // 告诉 spring:“这是一个数据库表对应的实体类” public class user { @id // 标记为主键 private long id; private string name; // 省略 getter/setter }
2. @transactional
作用:声明事务,确保方法内的数据库操作要么全部成功,要么全部回滚。
代码示例:
@service public class orderservice { @autowired private orderrepository orderrepository; @transactional // 开启事务 public void placeorder(order order) { orderrepository.save(order); // 保存订单 // 如果这里抛出异常(如库存不足),整个事务会回滚,订单不会被保存 } }
第六部分:aop(面向切面编程)
核心思想:在不修改原有代码的情况下,统一处理日志、权限、事务等横切关注点。
注解 | 说明 | 示例 |
---|---|---|
@aspect | 声明切面类 | @aspect @component public class loggingaspect { ... } |
@pointcut | 定义切入点表达式 | @pointcut("execution(* com.example.service.*.*(..))") public void servicemethods() {} |
@before | 前置通知 | @before("servicemethods()") public void logbefore(joinpoint jp) { ... } |
1. @aspect 和 @before
代码示例:
@aspect // 告诉 spring:“这是一个切面类” @component public class loggingaspect { // 定义切入点:拦截所有 service 层的方法 @pointcut("execution(* com.example.service.*.*(..))") public void servicemethods() {} // 前置通知:在方法执行前打印日志 @before("servicemethods()") public void logbefore(joinpoint joinpoint) { string methodname = joinpoint.getsignature().getname(); system.out.println("准备执行方法:" + methodname); } }
总结:注解的核心作用
场景 | 常用注解 | 类比解释 |
---|---|---|
管理对象 | @component , @service 等 | 告诉 spring:“这个类归你管!” |
依赖注入 | @autowired , @qualifier | 告诉 spring:“我需要这个,帮我拿!” |
处理 http 请求 | @restcontroller , @getmapping | 告诉 spring:“这个方法是处理某个 url 的!” |
读取配置 | @value , @configurationproperties | 告诉 spring:“把配置文件的值给我!” |
事务管理 | @transactional | 告诉 spring:“这个方法要保证事务!” |
到此这篇关于spring & spring boot 常用注解整理的文章就介绍到这了,更多相关spring boot 常用注解内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论