經驗整理-10-註解彙總-100-@

**java中常用的註解分三類:
1.JDK註解
2.Java第三方註解:spring、spring、springboot
3.自定義註解**

-----------JDK註解-----

1、@Resource
詳解
@Resource註解與@Autowired註解作用非常相似
@Resource的裝配順序:
(1)、@Resource後面沒有任何內容,默認通過name屬性去匹配bean,找不到再按type去匹配
(2)、指定了name或者type則根據指定的類型去匹配bean
(3)、指定了name和type則根據指定的name和type去匹配bean,任何一個不匹配都將報錯
@Autowired和@Resource兩個註解的區別:
(1)、@Autowired默認按照byType方式進行bean匹配(適合單例,多實例報錯,巧記,spring推薦單例自動注入),@Resource默認按照byName方式進行bean匹配(適合多實例按名稱注入)
(2)、@Autowired是Spring的註解,@Resource是J2EE的註解,這個看一下導入註解的時候這兩個註解的包名就一清二楚了
Spring屬於第三方的,J2EE是Java自己的東西,因此,建議使用@Resource註解,以減少代碼和Spring之間的耦合。

1、共同點
兩者都可以寫在字段和setter方法上。兩者如果都寫在字段上,那麼就不需要再寫setter方法。

2、不同點
(1)@Autowired
@Autowired爲Spring提供的註解,需要導入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入



-----------Java第三方註解-----


spring註解


@Configuration把一個類作爲一個IoC容器,它的某個方法頭上如果註冊
@Bean,就會作爲這個Spring容器中的Bean。
@Scope註解 作用域
@Lazy(true) 表示延遲初始化
@Service用於標註業務層組件、
@Controller用於標註控制層組件(如struts中的action)
@Repository用於標註數據訪問組件,即DAO組件。
@Component泛指組件,當組件不好歸類的時候,我們可以使用這個註解進- 行標註。
@Scope用於指定scope作用域的(用在類上)
@Autowired 默認按類型裝配,如果我們想使用按名稱裝配,可以結合@Qualifier註解一起使用。如下:
@Autowired @Qualifier(“personDaoBean”) 存在多個實例配合使用
@PostConstruct 初始化註解。構造方法之後,init之前
@PreDestroy destroy方法之後,實例
@Async異步方法調用



springboot註解


@SpringBootApplication:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration註解。其中@ComponentScan讓spring Boot掃描到Configuration類並把它加入到程序上下文。

@Configuration 等同於spring的XML配置文件;使用Java代碼可以檢查類型安全。

@EnableAutoConfiguration 自動配置。

@ComponentScan 組件掃描,可自動發現和裝配一些Bean。

@Component可配合CommandLineRunner使用,在程序啓動後執行一些基礎任務。

@RestController註解是@Controller和@ResponseBody的合集,表示這是個控制器bean,並且是將函數的返回值直 接填入HTTP響應體中,是REST風格的控制器。

@Autowired自動導入。

@PathVariable獲取參數。

@JsonBackReference解決嵌套外鏈問題。

@RepositoryRestResourcepublic配合spring-boot-starter-data-rest使用。

@ResponseBody:表示該方法的返回結果直接寫入HTTP response body中,一般在異步獲取數據時使用,用於構建RESTful的api。在使用@RequestMapping後,返回值通常解析爲跳轉路徑,加上@responsebody後返回結果不會被解析爲跳轉路徑,而是直接寫入HTTP response body中。比如異步獲取json數據,加上@responsebody後,會直接返回json數據。該註解一般會配合@RequestMapping一起使用。

@RestController:用於標註控制層組件(如struts中的action),@ResponseBody和@Controller的合集。

@ComponentScan:表示將該類自動發現掃描組件。

@Import:用來導入其他配置類。

@ImportResource:用來加載xml配置文件。

@Autowired:自動導入依賴的bean

@Value:注入Spring boot application.properties配置的屬性的值。

 

hibernate註解


@Entity:將pojo類標記成實體,可以指定一個name屬性,指定實體類的名稱
@Table:註釋改持久化類所映射的表
@UniqueConstraints:用於數據表的唯一約束 columnNames屬性
@Index用於數據庫建立索引
@DynamicInsert:指定用於插入記錄的insert語句是否在運行時動態生成。並且只插入那些非空字段。默認值時false
@DynamicUpdate:指定用於更新鉅鹿的update語句是否在運行是時動態生成,並且只更新那些修改過的字段,默認值是否false
@SelectBeforeUpdate:制動Hbiernate在更新某個持久化對象之前是否進行一次select(建議false)
@NotBlank只能作用在String上,不能爲null,而且調用trim()後,長度必須大於0

#swagger2註解

@Api()用於類; 表示標識這個類是swagger的資源
@ApiOperation()用於方法; 表示一個http請求的操作
@ApiParam()用於方法,參數,字段說明;表示對參數的添加元數據(說明或是否必填等)
@ApiModel()用於類 表示對類進行說明,用於參數用實體類接收
@ApiModelProperty()用於方法,字段;表示對model屬性的說明或者數據操作更改
@ApiIgnore()用於類,方法,方法參數 ;表示這個方法或者類被忽略
@ApiImplicitParam() 用於方法 ;表示單獨的請求參數
@ApiImplicitParams() 用於方法,包含多個 @ApiImplicitParam
Mybaits註解
@Select 簡單查詢
@Insert 簡單插入
@Update 簡單更新
@Delete 簡單刪除
@Param : 入參
@Results : 結果集合
@Result : 結果

lombok整理


@Data 註解在類上;提供類所有屬性的 getting 和 setting 方法,此外還提供了equals、canEqual、hashCode、toString 方法
@Setter :註解在屬性上;爲屬性提供 setting 方法
@Setter :註解在屬性上;爲屬性提供 getting 方法
@Log4j :註解在類上;爲類提供一個 屬性名爲log 的 log4j 日誌對象
@NoArgsConstructor :註解在類上;爲類提供一個無參的構造方法
@AllArgsConstructor :註解在類上;爲類提供一個全參的構造方法
@Cleanup : 可以關閉流
@Builder : 被註解的類加個構造者模式
@Synchronized : 加個同步鎖
@SneakyThrows : 等同於try/catch 捕獲異常
@NonNull : 如果給參數加個這個註解 參數爲null會拋出空指針異常
@Value : 註解和@Data類似,區別在於它會把所有成員變量默認定義爲private final修飾,並且不會生成set方法
@ToString:無需啓動調試器即可查看您的字段,註解會自動重寫對應的toStirng方法

 

-----------自定義便捷註解-----

參考:字段註解 https://blog.csdn.net/junmoxi/article/details/77744656?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158468996119724845047705%2522%252C%2522scm%2522%253A%252220140713.130056874..%2522%257D&request_id=158468996119724845047705&biz_id=0&utm_source=distribute.pc_search_result.none-task

一、定義可用的註解接口(理解爲對往暴露的一個可用的註解殼子,沒有實現複雜的邏輯)

先認識四種元註解,專門註解其他的註解:
巧記:文檔週期繼承目標
   @Documented –註解是否將包含在JavaDoc中
   @Retention –什麼時候使用該註解
   @Target –註解用於什麼地方
   @Inherited – 是否允許子類繼承該註解

@Target(ElementType.FIELD)//註解的作用範圍,就是註解是用在什麼地方的
@Retention(RetentionPolicy.RUNTIME)//註解的級別,就是註解能留存到什麼時候
@Documented
@Inherited
public @interface MyAnnotation {
    public String value();//註解可以接收的參數
}

二、註解處理器(自定義註解的業務實現邏輯入口在這)

參考:https://blog.csdn.net/u010590685/article/details/47066865?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158469116919725211922876%2522%252C%2522scm%2522%253A%252220140713.130056874..%2522%257D&request_id=158469116919725211922876&biz_id=0&utm_source=distribute.pc_search_result.none-task

 

public class Inject {
    public static void injectfeild(Object o){
         Class<?> clazz = o.getClass();  //獲得傳進來的類
         Field[] fields = clazz.getDeclaredFields();//通過反射獲取類的域(全局變量)
         for (Field field : fields) { 
            // 查看這個字段是否有我們自定義的註解類標誌的  
             if (field.isAnnotationPresent(MyAnnotation.class)) {  
                 MyAnnotation inject = field.getAnnotation(MyAnnotation.class);  //獲取到我們的註解
                 String value=inject.value();//獲取註解的參數
                 field.setAccessible(true);
                 try {
                  //處理註解想要實現的業務邏輯
                } catch (IllegalArgumentException | IllegalAccessException e) {

                    e.printStackTrace();
                }
             }
         }
    }
}

三、獲取獲取指定註解字段的值

  /**
     * @Author: Jiangxiaopeng
     * @Description:獲取指定註解字段的值
     * @Date: 2020/6/3
     * Object object2 已知對象
     * String reNameValue 註解字段指定重命名的名稱
     **/
    public static String getFeiledValueByObject(Object object2 , String reNameValue) throws IllegalAccessException {
        Field[] fields = object2.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(ReNameAnnotation.class)) {
                ReNameAnnotation reNameAnnotation = (ReNameAnnotation) field.getAnnotation(ReNameAnnotation.class);
                String reName= reNameAnnotation.reName();
                if(reNameValue.equals(reName)){
                    field.setAccessible(true);
                    Object o=field.get(object2);
                    String a1 =o.toString();
                    return a1;
                }
            }
        }
        return null;
    }

    /**
     * @Author: Jiangxiaopeng
     * @Description:獲取指定註解字段的值
     * @Date: 2020/6/3
     * ProceedingJoinPoint point 通過他拿到方法入參所有對象,然後遍歷
     * String reNameValue 註解字段指定重命名的名稱
     **/
    public static String getFeiledValueByPoint(ProceedingJoinPoint point,String reNameValue) throws IllegalAccessException {
//        Field[] fields = clazz.getDeclaredFields();
        Object[] args = point.getArgs();
        for (Object object : args) {
            Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(ReNameAnnotation.class)) {
                ReNameAnnotation reNameAnnotation = (ReNameAnnotation) field.getAnnotation(ReNameAnnotation.class);
               String reName= reNameAnnotation.reName();
               if(reNameValue.equals(reName)){
                   field.setAccessible(true);
                   Object o=field.get(object);
                   String a1 =o.toString();
                   return a1;
               }
            }
        }
        }
        return null;
    }



--------------------解決問題----------------

問題1:Java反射操作私有成員變量 Class can not access a member with modifiers "private"

解決:https://blog.csdn.net/hanchao5272/article/details/79435358
通過反射操作類的私有(private)成員變量時,需要通過field.setAccessible(true)將字段設置爲可以訪問的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章