註解&動態代理
阿新 • • 發佈:2020-10-26
註解&動態代理
1.註解
- 什麼是註解
Annotation,註解,是一種程式碼級別的說明,和類、介面、列舉在同一層次。
- 註解作用
- 編譯檢查:讓編譯器實現基本的編譯檢查,如@Override
- 程式碼分析:對程式碼進行分析,從而達到取代xml的目的
- 編寫文件:輔助生成幫助文件對應的內容
1.1JDK提供的註解
-
@Deprecated
表示被修飾的方法已經過時,過時的方法不建議使用,但仍可以使用。
@Deprecated public void method1(){ }
-
Override
JDK5表示覆寫父類的方法,JDK6還可以表示實現介面的方法。
@Override public void start() { super.start(); }
-
@SuppressWarnings("")
表示抑制警告,被修飾的類或方法如果存在編譯警告,將被編譯器忽略。
deprecation:忽略過時;
rawtypes:忽略型別安全;
unused:忽略不使用;
unchecked:忽略安全檢查;
null:忽略空指標;
all:忽略所有。
//3.抑制警告 //3.1deprecation,忽略過時警告 //null,忽略str空指標 @SuppressWarnings({"deprecation","null"}) public void method2(){ //3.2rawtypes,忽略型別安全警告,沒有使用泛型 //unused,忽略未使用警告 @SuppressWarnings({"rawtypes","unused"}) List list=new ArrayList(); String str=null; str.toString(); }
1.2自定義註解
- 定義註解
public @interface MyAnno1 {
}
- 定義帶屬性的註解
屬性格式:修飾符 返回值型別 屬性名() default 預設值;
- 修飾符預設且只能是public abstract
- 返回值型別:基本型別、字串String、Class、註解、列舉,以及以上型別的一維陣列
- 屬性名自定義
- default 預設值:可省略
public @interface MyAnno2 { String username() default "jack"; int age(); String[] strs(); Class clazz() default Date.class; MyAnno1 myAnno(); Color color(); } enum Color{ BLUE,RED,YELLOW }
1.2.1使用自定義註解
@MyAnno1
@MyAnno2(
username="tom",
age=18,
strs={"aaa","bbb","ccc"},
clazz=String.class,
myAnno=@MyAnno1,
color=Color.RED
)
public class AnnotationDemo2 {
}
1.2.2解析自定義註解
如果需要獲得註解上設定的資料,那麼就必須對註解進行解析,JDK提供java.lang.reflect.AnnotatedElement介面允許在執行時通過反射獲得註解。
1.3元註解
用於修飾註解的註解,可以修飾自定義註解以及JDK提供的註解。
1.4案例:自定義實現類似Junit@Test
- MyJunitTest
@Retention(RetentionPolicy.RUNTIME)
//定義註解的時候,需要通過元註解Retention說明當前自定義註解的作用域(Class,Source,Runtime)
@Target(ElementType.METHOD)
//定義註解的時候,需要通過元註解Target說明當前的自定義註解的目標物件
public @interface MyJunitTest {
long timeout() default -1;//自定義屬性,預設值為-1
}
/*
@Retention和@Target這兩個註解是必須的,否則Demo1中的method.isAnnotationPresent(MyJunitTest.class)結果一直都為false
*/
- Demo1
public class Demo1 {
static{
System.out.println("Demo1類被載入了");
}
@MyJunitTest(timeout=1000)
public void method1(){
System.out.println("--method1--");
}
@MyJunitTest
public void method2(){
System.out.println("--method2--");
}
@MyJunitTest
public void method3(){
System.out.println("--method3--");
}
public void method4(){
System.out.println("--method4--");
}
}
- Test1
//找到Demo1的所有帶有@MyJunitTest註解的方法
public class Test1 {
public static void main(String[] args) throws Exception {
//1.將Demo1的位元組碼檔案載入到記憶體,獲取位元組碼檔案在記憶體中的物件
Class clazz=Class.forName("com.itheima.annotation2.Demo1");
//2.獲取Demo1及其父類的所有方法
Method[] methods = clazz.getMethods();
//3.遍歷找出帶@MyJunitTest註解的方法
for (Method method:methods){
if (method.isAnnotationPresent(MyJunitTest.class)){
method.invoke(new Demo1());
System.out.println(method.getName());
}
}
}
}
2.動態代理
Proxy.newProxyInstance(ClassLoader loader,Class<?> interfaces, InvocationHandler h);
如:
Proxy.newProxyInstance(EncodingFilter.class.getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
})
2.1案例:解決get/post請求亂碼問題
- EncodingFilter
@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest request=(HttpServletRequest)servletRequest;
HttpServletRequest requestProxy=(HttpServletRequest) Proxy.newProxyInstance(EncodingFilter.class.getClassLoader(),
request.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//指定增強getParameter方法,再分別根據post和get請求進行處理
if("getParameter".equals(method.getName())){
String requestMethod = request.getMethod();
System.out.println(requestMethod);
if("get".equalsIgnoreCase(requestMethod)){
String value=(String) method.invoke(request,args);
System.out.println("value"+value);
return value;
//return new String(value.getBytes("ISO-8859-1"),"UTF-8");//測試發現無需轉碼就沒有亂碼
}else{
request.setCharacterEncoding("UTF-8");
return method.invoke(request,args);
}
}else{
return method.invoke(request,args);
}
}
});
filterChain.doFilter(requestProxy,servletResponse);
}
@Override
public void destroy() {
}
}