範例程式完整專案:
Java 基本內置 annotation
@Override
重寫父層的方法
@Deprecated
表示該方法再為雷會被棄用
@SuppressWarnings
主要的用處就是忽略警告信息
規定 annotation 可以放在哪裡
類別
- ElementType.TYPE : 能修飾類、接口、枚舉、注解
- ElementType.FIELD : 能修飾字段、枚舉的常量
- ElementType.METHOD : 能修飾方法
- ElementType.PARAMETER : 能修飾方法參數
- ElementType.CONSTRUCTOR : 能修飾構造函數
- ElementType.LOCAL_VARIABLE : 能修飾局部變量
- ElementType.ANNOTATION_TYPE : 能修飾注解 (元注解就是此種)
- ElementType.PACKAGE : 能修飾包
- ElementType.TYPE_PARAMETER: (java8)類型參數聲明
- ElementType.TYPE_USE: (java8)使用類型
- ElementType.MODULE: (java9)模組聲明
- ElementType.RECORD_COMPONENT: (java16)記錄組件
原始碼
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.annotation;
/**
* The constants of this enumerated class provide a simple classification of the
* syntactic locations where annotations may appear in a Java program. These
* constants are used in {@link java.lang.annotation.Target Target}
* meta-annotations to specify where it is legal to write annotations of a
* given type.
*
* <p>The syntactic locations where annotations may appear are split into
* <em>declaration contexts</em>, where annotations apply to declarations, and
* <em>type contexts</em>, where annotations apply to types used in
* declarations and expressions.
*
* <p>The constants {@link #ANNOTATION_TYPE}, {@link #CONSTRUCTOR}, {@link
* #FIELD}, {@link #LOCAL_VARIABLE}, {@link #METHOD}, {@link #PACKAGE}, {@link
* #MODULE}, {@link #PARAMETER}, {@link #TYPE}, and {@link #TYPE_PARAMETER}
* correspond to the declaration contexts in JLS 9.6.4.1.
*
* <p>For example, an annotation whose interface is meta-annotated with
* {@code @Target(ElementType.FIELD)} may only be written as a modifier for a
* field declaration.
*
* <p>The constant {@link #TYPE_USE} corresponds to the type contexts in JLS
* 4.11, as well as to two declaration contexts: class and interface
* declarations (including annotation declarations) and type parameter
* declarations.
*
* <p>For example, an annotation whose interface is meta-annotated with
* {@code @Target(ElementType.TYPE_USE)} may be written on the class or
* interface of a field (or within the class or interface of the field, if it
* is a nested or parameterized class or interface, or array class), and may
* also appear as a modifier for, say, a class declaration.
*
* <p>The {@code TYPE_USE} constant includes class and interface declarations
* and type parameter declarations as a convenience for designers of
* type checkers which give semantics to annotation interfaces. For example,
* if the annotation interface {@code NonNull} is meta-annotated with
* {@code @Target(ElementType.TYPE_USE)}, then {@code @NonNull}
* {@code class C {...}} could be treated by a type checker as indicating that
* all variables of class {@code C} are non-null, while still allowing
* variables of other classes to be non-null or not non-null based on whether
* {@code @NonNull} appears at the variable's declaration.
*
* @author Joshua Bloch
* @since 1.5
* @jls 9.6.4.1 @Target
* @jls 4.1 The Kinds of Types and Values
*/
public enum ElementType {
/** Class, interface (including annotation interface), enum, or record
* declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation interface declaration (Formerly known as an annotation type.) */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE,
/**
* Module declaration.
*
* @since 9
*/
MODULE,
/**
* Record component
*
* @jls 8.10.3 Record Members
* @jls 9.7.4 Where Annotations May Appear
*
* @since 16
*/
RECORD_COMPONENT;
}
annotation 生命週期: @Retention
類別
- RetentionPolicy.SOURCE: 不會編譯進去class
- RetentionPolicy.CLASS: 會編譯進去class,但是不會執行
- RetentionPolicy.RUNTIME: 會編譯進去class,會執行
原始碼
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.annotation;
/**
* Annotation retention policy. The constants of this enumerated class
* describe the various policies for retaining annotations. They are used
* in conjunction with the {@link Retention} meta-annotation interface to
* specify how long annotations are to be retained.
*
* @author Joshua Bloch
* @since 1.5
*/
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
Spring AOP
- 環境: grails 5.3.5
使用注入
- grails-app/conf/spring/resources.groovy
package spring
import work.pollochang.aop.ExampleInterceptor
// Place your Spring DSL code here
beans = {
/*
* Spring AOP 設定
*/
xmlns aop: "http://www.springframework.org/schema/aop"
// 初始化攔截器
aspectBean(ExampleInterceptor)
aop.config("proxy-target-class": true) {
}
}
AOP 程式片段
- work.pollochang.aop.ExampleInterceptor.groovy
package work.pollochang.aop
import org.aspectj.lang.annotation.AfterReturning
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.springframework.stereotype.Component
/**
* 範例攔截器
* 使用 Spring AOP
*
* @doc https://docs.spring.io/spring-framework/docs/4.3.15.RELEASE/spring-framework-reference/html/aop.html
*/
@Aspect
@Component
//先不要使用 @Slf4j 會出現兩次
class ExampleInterceptor {
/**
* 攔截 package
*/
@Before("execution(* work.pollochang.example.ex1.*.*(..))")
static void beforeMethodExecution() {
println "這個是指定 package 攔截: 執行方法之前"
}
/**
* 攔截 package
*/
@AfterReturning(pointcut = "execution(* work.pollochang.example.ex1.*.*(..))", returning = "result")
static void afterMethodExecution(Object result) {
println "這個是指定 package 攔截: 執行方法之後"
}
/**
* 攔截 指定 annotation
*/
// @Before("@annotation(org.springframework.transaction.annotation.Transactional)")
@Before("@annotation(work.pollochang.annotation.Test1)")
void test() {
println "這個是使用 annotation 攔截"
}
}
執行程式範例
指定 package 攔截
- work.pollochang.example.ex1.ExampleService.groovy
package work.pollochang.example.ex1
/**
* 範例 Service
*/
class ExampleService {
/**
* 範例執行方法
*/
void doSomething() {
println "Doing something..."
// 模擬程式操作
Thread.sleep(1000)
println "Done!"
}
}
指定 annotation
- work.pollochang.annotation.Test1.java
這邊先建立一個 annotation
package work.pollochang.annotation;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Test1 {
}
- work.pollochang.example.ex2.Example2Service.groovy
package work.pollochang.example.ex2
import work.pollochang.annotation.Test1
class Example2Service {
/**
* 範例執行方法
*/
@Test1
void doSomething() {
println "Doing something..."
// 模擬程式操作
Thread.sleep(1000)
println "Done!"
}
}