AOP(注解、反射、代理)详解

avatar
avatar
云惠网小编
2846
文章
1
评论
2021年4月7日11:17:43 评论 15 次浏览 3736字阅读12分27秒
摘要

AOP(注解、反射、代理)详解Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。import static java.lang.annotation.ElementType.ANNOTATION_TYPE;import

输出:
getUserList
执行时间:0
login
执行时间:0
logout
执行时间:0

Java 反射

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ TYPE, PARAMETER, ANNOTATION_TYPE })
@Retention(value=RetentionPolicy.RUNTIME)//注解可以被写入class中
public @interface ClassAnnotation {
public String url() default "/";//注解的属性
}
import java.lang.reflect.Field;
@ClassAnnotation
public class TestClass1 {
private String url;
public String geturl() {
return this.url;
}
public void seturl(@paramAnnotation String url) {
this.url=url;
}
public static void main(String[] args) throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
// TODO Auto-generated method stub
Class clazz=TestClass1.class;
ClassAnnotation a=(ClassAnnotation)clazz.getAnnotation(ClassAnnotation.class);
System.out.println(a.url());
TestClass1 tc=(TestClass1)clazz.newInstance();
Field f=clazz.getDeclaredField("url");
f.setAccessible(true);
f.set(tc, a.url());
System.out.println(tc.geturl());
}
}

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
AOP主要功能:日志记录,性能统计,安全控制,事务处理,异常处理等等wn及扩展
接下来通过代码来理解一下AOP思想。

测试类:
import java.util.Date;
public class TestAOP {
public static void main(String[] args) {
// TODO Auto-generated method stub
//AOP是面向切面编程,测试性能,统一日志,事务管理
UserService us=(UserService) new DyProxy().getProxyObject(new UserServiceeImp());
us.getUserList();
us.login();
us.logout();
}
}

AOP(注解、反射、代理)详解

动态代理实现AOP

代理类:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Date;
/**
* 动态代理技术
*
*/
public class DyProxy {
private Object toProxyObj;
public Object getProxyObject(Object object) {
this.toProxyObj=object;
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),new InvocationHandler()
{
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
long startTime=new Date().getTime();
Object result=method.invoke(toProxyObj,args);
long totalTime=new Date().getTime();
System.out.println("执行时间:"+(totalTime-startTime));
return result;
}
});
}
}
输出:main方法执行了。。。

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

Java 注解

(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。
Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。

student类:
package fanshe.main;
public class Student {
public static void main(String[] args) {
System.out.println("main方法执行了。。。");
}
}

反射main方法:

方法类:
public class UserServiceeImp implements UserService {
@Override
public void login() {
// TODO Auto-generated method stub
System.out.println("login");
}
@Override
public void logout() {
// TODO Auto-generated method stub
System.out.println("logout");
}
@Override
public void getUserList() {
// TODO Auto-generated method stub
System.out.println("getUserList");
}
}
测试类:
package fanshe.main;
import java.lang.reflect.Method;
/**
* 获取Student类的main方法、不要与当前的main方法搞混了
*/
public class Main {
public static void main(String[] args) {
try {
//1、获取Student对象的字节码
Class clazz = Class.forName("fanshe.main.Student");
//2、获取main方法
Method methodMain = clazz.getMethod("main", String[].class);//第一个参数:方法名称,第二个参数:方法形参的类型,
//3、调用main方法
// methodMain.invoke(null, new String[]{"a","b","c"});
//第一个参数,对象类型,因为方法是static静态的,所以为null可以,第二个参数是String数组,这里要注意在jdk1.4时是数组,jdk1.5之后是可变参数
//这里拆的时候将  new String[]{"a","b","c"} 拆成3个对象。。。所以需要将它强转。
methodMain.invoke(null, (Object)new String[]{"a","b","c"});//方式一
// methodMain.invoke(null, new Object[]{new String[]{"a","b","c"}});//方式二
} catch (Exception e) {
e.printStackTrace();
}
}
}

本文转自 https://blog.csdn.net/qq_44952665/article/details/115446333

腾讯云618
avatar
2w 字长文爆肝 JVM 经典面试题!太顶了! java

2w 字长文爆肝 JVM 经典面试题!太顶了!

如果你是中高级程序员,那我相信你一定被面试官问过JVM。下次再被问到JVM,你直接把老周的这篇文章丢给他吧!话不多说,让我们直接进入主题吧。JVM内存结构,常见异常,调优参数,调优...
腾讯云618
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: