Spring各種注解的含義及用法(持續更新)


1.基礎(SpringMVC和SpringBoot都有在用)

@Controller

通常用於標注在控制層類上。

@Service

通常用於標注在業務層實現類上。可以設置自定義service類的別名,在控制層引入時就需要根據設置的別名進行引入。

@Mapper

不需要在啟動類上配置掃描,會在運行時通過動態代理生成實現類。

@Component

泛指組件,當組件不好歸屬於控制層/業務層 的時候,我們可以使用這個注解進行標注

@ServletComponentScan

在SpringBootApplication上使用@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通過@WebServlet、@WebFilter、@WebListener注解自動注冊,無需其他代碼

@ComponentScan(basePackages ={'可配置掃描的路徑"})

掃描配置路徑中的類,生成實現類,把依賴的組件注入進去

@Autowired

關聯依賴的組件,當該組件接口有2個以上的實現類時,須添加 @Qualifier("實現類的名稱") 說明具體是哪個實現類 使用了該注解可不用寫 get set方法 Spring會幫你完成

@Primary

當2個類實現同一個接口時,在使用改接口時,把這個注解加在其中一個實現類上,就會優先選擇使用改注解的類

@Scope("prototype")

默認是singleton單例模式的,prototype表示每次調用時都會創建一個新的對象

@Bean

注解將會告訴 Spring 其修飾的方法將會返回一個對象,該方法要注冊為 Spring 應用上下文的 bean,默認情況下bean 的 ID 與帶有 @Bean 注解的方法名保持一致。可以 @Bean(name="定義其他名稱")

@Configuration

標注在類上,相當於把該類作為spring的xml配置文件中的 ,作用為:配置spring容器(應用上下文) @Configuration注解的spring容器加載方式,用AnnotationConfigApplicationContext替換ClassPathXmlApplicationContext
ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);

如果加載spring-context.xml文件:
ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");

@Param

標記在dao層方法中的普通參數前,可以在xml中不需要使用 parameterType 進行聲明可以直接使用,標記在實體類參數前,需要在xml中使用 別名.屬性 的方式使用實體類的變量,建議實體類參數不加,不加可以在xml中直接使用 變量名。 在使用List作為查詢條件時,需要設置 @Param 否則會報錯 接口方法示例:
List<Map> getTimeLineColumn(@Param("cbIds") List<String> cbIds)throws Exception;

xml中示例:

<select id="getTimeLineColumn" resultType="Map">
    select cu.USERNAME,cu.ID
    from CASEBANK cb
    join CASEUSER cu on cb.CUID=cu.id
    WHERE cb.ID in
    <foreach collection="cbIds" item="cbid" open="(" separator="," close=")">
        #{cbid}
    </foreach>
    GROUP BY cu.ID,cu.USERNAME
    ORDER BY id
</select>

2.SpringBoot中常見注解

@RestController

@RestController注解相當於@ResponseBody + @Controller合在一起的作用。 1) 如果只是使用@RestController注解Controller,則Controller中的方法無法返回jsp頁面,或者html,配置的視圖解析器 InternalResourceViewResolver不起作用,返回的內容就是Return 里的內容。 2) 如果需要返回到指定頁面,則需要用 @Controller配合視圖解析器InternalResourceViewResolver才行。 如果需要返回JSON,XML或自定義mediaType內容到頁面,則需要在對應的方法上加上@ResponseBody注解。

@SpringBootApplication

用於標注啟動類上,相當於@EnableAutoConfiguration(自動注入相關配置類)、@ComponentScan和@Configuration的合集。

@ImportResource

用來加載xml配置文件

@PathVaribale

獲取restful請求中的數據
@RestController
public class HelloController {
 
  @RequestMapping(value="/hello/{id}",method= RequestMethod.GET)
  public String sayHello(@PathVariable("id") Integer id){
    return "id:"+id;
  }
}

@RequestParam

獲取請求參數的值 localhost:8080/hello?id=1000
@RestController
public class HelloController {
 
  @RequestMapping(value="/hello",method= RequestMethod.GET)
  public String sayHello(@RequestParam("id") Integer id){
    return "id:"+id;
  }
}

@RequestBody

注解可以接收json格式的數據,並將其轉換成對應的數據類型
當前台界面使用GET或POST方式提交數據時,數據編碼格式由請求頭的ContentType指定。分為以下幾種情況:
1. application/x-www-form-urlencoded,這種情況的數據@RequestParam、@ModelAttribute可以處理,@RequestBody也可以處理。
2. multipart/form-data,@RequestBody不能處理這種格式的數據。(form表單里面有文件上傳時,必須要指定enctype屬性值為multipart/form-data,意思是以二進制流的形式傳輸文件。)
3. application/json、application/xml等格式的數據,必須使用@RequestBody來處理。
用於post請求,不能用於get請求

@RequestParam 和 @RequestBody 一起使用在接口上時

@PostMapping(value = ConstScheduleUrl.COMMON_ADDACCESSORYLIST)
public ResponseResult addAccessoryList(@RequestParam("workPlanId") String workPlanId,@RequestBody ScheduleCommonWorkPlanVO commonWorkPlanVO){
    commonWorkPlanCodeService.commonHandleAccessory(commonWorkPlanVO,workPlanId);
    return ResponseResult.success();
}

@EnableScheduling

加在SpringBoot的啟動類上開啟對定時任務的支持,配合@Scheduled使用

@Scheduled

Scheduled注解中有以下幾個參數:
cron
zone
fixedDelay和fixedDelayString
fixedRate和fixedRateString
initialDelay和initialDelayString
1.cron是設置定時執行的表達式,如 0 0/5 * * * ?每隔五分鍾執行一次
2.zone表示執行時間的時區
3.fixedDelay 和fixedDelayString 表示一個固定延遲時間執行,上個任務完成后,延遲多長時間執行
4.fixedRate 和fixedRateString表示一個固定頻率執行,上個任務開始后,多長時間后開始執行
5.initialDelay 和initialDelayString表示一個初始延遲時間,第一次被調用前延遲的時間

@EnableCaching

開啟緩存,配合@Cacheable使用 value:緩存位置名稱,不能為空,如果使用EHCache,就是ehcache.xml中聲明的cache的name key:緩存的key,默認為空,既表示使用方法的參數類型及參數值作為key,支持SpEL condition:觸發條件,只有滿足條件的情況才會加入緩存,默認為空,既表示全部都加入緩存,支持SpEL
//將緩存保存進andCache,並使用參數中的userId加上一個字符串(這里使用方法名稱)作為緩存的key     
@Cacheable(value="andCache",key="#userId + 'findById'")    
public SystemUser findById(String userId) {    
    SystemUser user = (SystemUser) dao.findById(SystemUser.class, userId);          
    return user ;           
}

//將緩存保存進andCache,並當參數userId的長度小於32時才保存進緩存,默認使用參數值及類型作為緩存的key    
@Cacheable(value="andCache",condition="#userId.length < 32")    
public boolean isReserved(String userId) {    
    System.out.println("hello andCache"+userId);    
    return false;    
}    

@CacheConfig

含義:指定要用於該類的每個高速緩存操作的高速緩存的名稱可以由單個類級定義代替。即該方式屬於類級別操作。 示例:
//定義該類中的所有緩存在CACHE_SYS_PAPER 里
@Service
@CacheConfig(cacheNames = { CacheConstants.CACHE_SYS_PAPER })
public class ScheduleTrainPaperService {
    ...
}

@Cacheable

含義:當調用該注解聲明的方法時,會先從緩存中查找,判斷是否有key相同緩存的數據,如果有,就直接返回數據,如果沒有,執行方法,然后把返回的數據以鍵值的方式存儲到緩存中,方便下次同樣參數請求時,直接從緩存中返回數據。
@Cacheable支持如下幾個參數:
cacheNames:緩存位置的一段名稱,不能為空,和value一個含義。
value:緩存位置的一段名稱,不能為空,和cacheNames一個含義。
key:緩存的key,默認為空,表示使用方法的參數類型及參數值作為key,支持SpEL。
keyGenerator:指定key的生成策略。
sync: 默認false,設置為true 表示並發訪問時,多個線程只有1個線程可以訪問數據庫,其他線程都會等待直到緩存可用
condition:觸發條件,滿足條件就加入緩存,默認為空,表示全部都加入緩存,支持SpEL。
//SpEL方式定義key
CacheConstants.CACHE_ROOT_METHOD_NAME_ID="#root.methodName + #id"

@Cacheable(key = CacheConstants.CACHE_ROOT_METHOD_NAME_ID ,sync =true)
public ScheduleTrainOption get(Integer id) {
   return trainOptionMapper.get(id);
}

@CacheEvict

含義:當存在相同key的緩存時,把緩存清空,相當於刪除。
cacheNames:緩存位置的一段名稱,不能為空,和value一個含義。
value:緩存位置名稱,不能為空,和cacheNames一個含義
key:緩存的key,默認為空,表示使用方法的參數類型及參數值作為key,支持SpEL
condition:觸發條件,只有滿足條件的情況才會清除緩存,默認為空,支持SpEL
allEntries:true表示清除value中的全部緩存,默認為false

@CahePut

@CachePut也可以聲明一個方法支持緩存功能。與@Cacheable不同的是使用@CachePut標注的方法在執行前不會去檢查緩存中是否存在之前執行過的結果,而是每次都會執行該方法,並將執行結果以鍵值對的形式存入指定的緩存中

@EnableTransactionManagement

開啟事務支持,然后在訪問數據庫的Service方法上添加注解 @Transactional 便可 關於事務管理器,不管是JPA還是JDBC等都實現自接口 PlatformTransactionManager 如果你添加的是 spring-boot-starter-jdbc 依賴,框架會默認注入 DataSourceTransactionManager 實例。如果你添加的是 spring-boot-starter-data-jpa 依賴,框架會默認注入 JpaTransactionManager 實例

@MapperScan

通過使用@MapperScan可以指定要掃描的Mapper類的包的路徑
@SpringBootApplication
@MapperScan("com.lz.water.monitor.mapper")

//也可以同時掃描多個包
@SpringBootApplication  
@MapperScan({"com.kfit.demo","com.kfit.user"})  

//如果mapper類沒有在Spring Boot主程序可以掃描的包或者子包下面,可以使用如下方式進行配置
@SpringBootApplication  
@MapperScan({"com.kfit.*.mapper","org.kfit.*.mapper"})  

@ConfigurationProperties

注解支持兩種方式
加在類上,需要和@Component注解,結合使用.代碼如下:
@Component
@ConfigurationProperties(prefix = "com.example.demo")

通過@Bean的方式進行聲明,這里我們加在啟動類即可,代碼如下

@Bean
@ConfigurationProperties(prefix = "com.example.demo")

prefix 全部要改成小寫,不可以配合@value 使用會報錯

java.lang.IllegalArgumentException: Could not resolve placeholder 'defaultPoints' in value "${defaultPoints}"

@ProtertySource

.yml 格式不支持 @PropertySource 注解導入配置 用法1- @PropertySource和@Value
@PropertySource("classpath:jdbc.properties")
@Value(${jdbc.driver})
private String driver;

也可以配合@ConfigurationProperties 使用

@ExceptionHandler

統一處理某一類異常,從而能夠減少代碼重復率和復雜度

@ControllerAdvice

異常集中處理,更好的使業務邏輯與異常處理剝離開 拋出Exception異常就可以被捕獲到,也可以在@ExceptionHandler(定義自己的異常類)

@RestControllerAdvice

在spring 3.2中,新增了@ControllerAdvice,@RestControllerAdvice 注解,可以用於定義@ExceptionHandler、@InitBinder、@ModelAttribute,
並應用到所有@RequestMapping中
主要配合@ExceptionHandler使用,統一處理異常情況。下面的ResponseEntity、ResponseData 都是項目自定義的返回對象
controller層統一處理異常,service及其他被調用代碼塊只負責拋出異常即可,
service層不顯式拋出自定義異常的話,可以通過自定義全局異常處理類可以統一拋出某個自定義提示

例如如下代碼:
定義全局異常處理類
@RestControllerAdvice
public class RmcpExceptionHandler {
    private final static Logger logger = LoggerFactory.getLogger(RmcpExceptionHandler.class);

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResponseResult handle(Exception e) {
        ResponseResult result = new ResponseResult();
        if (e instanceof RmcpException) {
            // 系統自定義異常
            ....
        } else if (e instanceof ConstraintViolationException) {
            ....
        } else if (e instanceof MethodArgumentTypeMismatchException) {
           ...
        } else if (e instanceof MethodArgumentNotValidException){
            ...
        }
        else if (e instanceof HttpMessageNotReadableException) {
            ...
        } else {
            // 未知異常
            ...
        }

        e.printStackTrace();
        return result;
    }
}

@ResponseStatus

可以將某種異常映射為HTTP狀態碼

@ConditionalOnMissingBean

該注解表示,如果存在它修飾的類的bean,則不需要再創建這個bean; 可以給該注解傳入參數例如@ConditionOnMissingBean(name = "example"), 這個表示如果name為“example”的bean存在,這該注解修飾的代碼塊不執行
@Bean
    @ConditionalOnMissingBean(name = "imageValidateCodeGenerator")
    public ValidateCodeGenerator imageValidateCodeGenerator() {
        ImageCodeGenerator codeGenerator = new ImageCodeGenerator();
        codeGenerator.setSecurityProperty(securityProperties);
        return codeGenerator;
    }

測試發現, @ConditionOnMissingBean 只能在@Bean 注釋的方法上使用,不能再@Component 注釋的類上使用

@PostConstruct

被@PostConstruct修飾的方法會在服務器加載Servle的時候運行,並且只會被服務器執行一次。PostConstruct在構造函數之后執行,init()方法之前執行。

@PreDestroy

PreDestroy()方法在destroy()方法執行執行之后執行,如下: 我現在要說的是用實例說明它有什么作用。 比如說我有一種情況,在我的servlet初始化加載之前我想處理一些東西,像加載緩存等等。 怎么做。@PostConstruct就派上用場了。那為什么這玩意用的不多呢,這是因為如果初始化之前我們要加載或處理某些玩意完全可以在構造器初始化時就處理了,但這種方法需要自己重寫構造器

@Transactional

常用傳參:
1.propagation=事務傳播行為
1. TransactionDefinition.PROPAGATION_REQUIRED:
如果當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務。這是默認值。
2. TransactionDefinition.PROPAGATION_REQUIRES_NEW:
創建一個新的事務,如果當前存在事務,則把當前事務掛起。 內部的事務獨立運行,在各自的作用域中,可以獨立的回滾或者提交; 而外部的事務將不受內部事務的回滾狀態影響 3. TransactionDefinition.PROPAGATION_SUPPORTS:
如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續運行。 4. TransactionDefinition.PROPAGATION_NOT_SUPPORTED:
以非事務方式運行,如果當前存在事務,則把當前事務掛起。 5. TransactionDefinition.PROPAGATION_NEVER:
以非事務方式運行,如果當前存在事務,則拋出異常。 6. TransactionDefinition.PROPAGATION_MANDATORY:
如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。 7. TransactionDefinition.PROPAGATION_NESTED:
如果當前存在事務,則創建一個事務作為當前事務的嵌套事務來運行; 如果當前沒有事務,則該取值等價於TransactionDefinition.PROPAGATION_REQUIRED。

PROPAGATION_REQUIRES_NEW和PROPAGATION_NESTED的區別

REQUIRES_NEW:啟動一個新的,不依賴環境的“內部”事務,這個事務將被完全commited或rolled back 而不依賴於外部事務,它擁有自己的隔離范圍,自己的鎖等等,當內部事務開始執行時,外部事務將被掛起,內部事務結束時,外部事務將繼續執行。

NESTED:如果外部事務commit,嵌套事務也會被commit;如果外部事務roll back,嵌套事務也會被 roll back。

開始一個嵌套的事務,它是已經存在事務的一個真正的子事務,嵌套事務開始執行時,它將取得一個savepoint,如果這個嵌套事務失敗,我們將回滾到此savepoint,嵌套事務是外部事務的一部分,只有外部事務結束后它才會被提交


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM