反射
获取Class
对象的三种方式
1 2 3 4 5 6 7 8
| Class<?> obClass = new Object().getClass();
Class<?> obClass = Object.class;
Class<?> obClass = Class.forName("com.package");
|
构造器
获取公有构造器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Constructor<?>[] constructors = aClass.getConstructors(); for (Constructor<?> constructor : constructors) { System.out.println(constructor); }
Constructor<?> constructor1 = aClass.getConstructor(); System.out.println(constructor1);
Constructor<?> constructor2 = aClass.getConstructor(int.class, String.class); System.out.println(constructor2);
TestBean t1 = (TestBean) constructor1.newInstance(); System.out.println(t1);
|
获取私有构造器
1 2 3 4 5 6 7 8 9 10 11 12 13
| Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors(); for (Constructor<?> declaredConstructor : declaredConstructors) { System.out.println(declaredConstructor); }
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(int.class); System.out.println(declaredConstructor);
declaredConstructor.setAccessible(true); TestBean t2 = (TestBean) declaredConstructor.newInstance(1); System.out.println(t2);
|
方法
获取公有方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Method[] methods = aClass.getMethods(); for (Method method : methods) { System.out.println(method); }
Method method = aClass.getMethod("setKey", String.class);
TestBean t1 = new TestBean();
method.invoke(t1, "八嘎雅鹿");
System.out.println(t1);
|
获取私有方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Method[] declaredMethods = aClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod); }
Method test = aClass.getDeclaredMethod("getUid");
TestBean t2 = new TestBean();
test.setAccessible(true);
String result = (String) test.invoke(t2);
|
变量
获取公有变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| Field[] fields = aClass.getFields(); for (Field field : fields) { System.out.println(field); }
Field field = aClass.getField("name");
TestBean t1 = new TestBean();
field.set(t1, "小明"); System.out.println(t1.name);
Field field2 = aClass.getField("name");
TestBean t2 = new TestBean(); t2.name = "小红";
String value = (String) field2.get(t2); System.out.println(value);
|
获取私有变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| Field[] declaredFields = aClass.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println(declaredField); }
Field declaredField = aClass.getDeclaredField("key");
TestBean t3 = new TestBean();
declaredField.setAccessible(true);
declaredField.set(t3, "id"); System.out.println(t3.getKey());
Field declaredField = aClass.getDeclaredField("key");
TestBean t4 = new TestBean(); t4.setKey("aaa");
String key = (String) declaredField.get(t4); System.out.println(key);
|
代理
代理模式
通过创建一个代理对象
来控制对原始对象
的访问。代理模式涉及两个角色:代理角色
和真实角色
,二者实现同一个接口。代理类负责代理真实类,为真实类提供控制访问的功能,真实类则完成具体的业务逻辑。使用代理模式主要有两个目的:一是保护目标对象,二是增强目标对象。
如下,真实类先实现二者之间的接口
1 2 3 4 5
| public interface ArmoredWarrior { void weapon(); void skill(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class XingTian implements ArmoredWarrior{
@Override public void weapon() { System.out.println("火刑天烈剑"); }
@Override public void skill() { System.out.println("天烈斩"); } }
|
静态代理
通过一个专用的代理类,实现真实类和代理类之间的接口,在调用代理类中的方法时,会执行前置增强、真实类对应方法以及后置增强,如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class ProxyClass implements ArmoredWarrior{ private final XingTian xingTian;
public ProxyClass(XingTian xingTian) { this.xingTian = xingTian; }
@Override public void weapon() { before(); xingTian.weapon(); after(); }
@Override public void skill() { before(); xingTian.skill(); after(); }
private void before() { System.out.println("前置增强"); }
private void after() { System.out.println("后置增强"); } }
|
静态代理在使用时
1 2 3 4 5
| XingTian xingTian = new XingTian(); ProxyClass proxyClass = new ProxyClass(xingTian);
proxyClass.weapon(); proxyClass.skill();
|
动态代理
通过java
自带的java.lang.reflect.Proxy
类来实现动态代理功能,在运行时动态生成一个代理对象,代理对象实现和原始类一样的接口,并将方法调用转发给真实对象,同时可以在方法调用前后执行额外的增强处理,通过反射机制实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| ArmoredWarrior target = new XingTian();
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Class<?>[] interfaces = new Class[]{ArmoredWarrior.class};
InvocationHandler handler = new InvocationHandler() {
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("前置增强"); Object result = method.invoke(target, args); System.out.println("后置增强"); return result; } };
ArmoredWarrior armoredWarrior = (ArmoredWarrior) Proxy.newProxyInstance(classLoader, interfaces, handler);
armoredWarrior.weapon(); armoredWarrior.skill();
|