Введение в метод newProxyInstance()
Метод newInstance() класса Proxy имеет три параметра:
Загрузчик ClassLoader:Это тип загрузчика классов, вам не нужно обращать на него внимание, вам просто нужно знать, как его получить: MyInterface.class.getClassLoader() может получить объект ClassLoader, да, если у вас есть класс объект Получить объект ClassLoader;Интерфейсы класса []:Укажите, какие интерфейсы должны быть реализованы объектом, возвращаемым методом newProxyInstance(). Да, вы можете указать несколько интерфейсов. Например, в приведенном выше примере мы указали только один интерфейс: Class[] cs = {MyInterface.class} ;Обработчик вызова h:Это самый важный параметр! Это интерфейс! Его зовут обработчик вызовов! Независимо от того, какой метод вы вызываете для прокси-объекта, он вызывает метод invoke() InvocationHandler!
Введение в АОП
Аспектно-ориентированное программирование (АОП) — горячая тема. АОП, что в Китае примерно переводится как «аспектно-ориентированное программирование».
- «Аспектно-ориентированное программирование», такое название не очень легко понять и может ввести в заблуждение.
- Автор не раз слышал речи типа "ООП/ООД11 вот-вот устареет, АОП - метод разработки ПО нового поколения". В АОП значение аспекта может быть более подходящим для понимания как «аспект». Поэтому автор предпочитает перевод «аспектно-ориентированное программирование». Технология, которая динамически и единообразно добавляет функции в программу без изменения исходного кода, может быть достигнута с помощью динамических агентов предварительной компиляции и времени выполнения.
- АОП на самом деле является продолжением шаблона проектирования GoF. Шаблон проектирования неустанно преследует развязку между вызывающей и вызываемой сторонами и повышает гибкость и масштабируемость кода. Можно сказать, что АОП является реализацией этой цели.
Объекты приложения делают только то, что должны делать — завершают бизнес-логику — и ничего больше. Они не несут ответственности (и даже не осведомлены) о других проблемах системного уровня, таких как ведение журнала или поддержка транзакций.
Основная функция АОП
Ведение журнала, статистика производительности, контроль безопасности, обработка транзакций, обработка исключений и т. д. wn и расширения
Основная цель АОП
Отделить от кода бизнес-логики код ведения журнала, статистики производительности, контроля безопасности, обработки транзакций, обработки исключений и т. д. Разделив эти поведения, мы надеемся, что сможем разделить их на методы, которые не управляют бизнес-логикой, а затем изменить этот код, который не влияет на бизнес-логику, когда он ведет себя.
Реализация АОП
package org.java.base.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MainApp1 {
public static void main(String[] args) {
ClassLoader loader = MainApp1.class.getClassLoader();
Class[] cs = {Waiter.class};
Waiter target = new MyWaiter();
MyInvocationHandler h = new MyInvocationHandler(target);
Waiter waiter = (Waiter)Proxy.newProxyInstance(loader, cs, h);
waiter.serve();
}
}
class MyInvocationHandler implements InvocationHandler {
public Waiter target;
public MyInvocationHandler(Waiter target) {
this.target = target;
}
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;
}
}
package org.java.base.proxy;
/**
* 后置增强
* @author Liuhaihua
*
*/
public interface AfterAdvice {
public void after();
}
package org.java.base.proxy;
/**
* 前置增强
* @author Liuhaihua
*
*/
public interface BeforeAdvice {
public void before();
}
package org.java.base.proxy;
public class MyWaiter implements Waiter {
public void serve() {
System.out.println("服务...");
}
}
package org.java.base.proxy;
public interface Waiter {
// 服务
public void serve();
}
package org.java.base.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 它用来生成代理对象
* 它需要所有的参数
* * 目标对象
* * 增强
* @author cxf
*/
/**
* 1. 创建代理工厂
* 2. 给工厂设置三样东西:
* * 目标对象:setTargetObject(xxx);
* * 前置增强:setBeforeAdvice(该接口的实现)
* * 后置增强:setAfterAdvice(该接口的实现)
* 3. 调用createProxy()得到代理对象
* * 执行代理对象方法时:
* > 执行BeforeAdvice的before()
* > 目标对象的目标方法
* > 执行AfterAdvice的after()
* @author cxf
*
*/
public class ProxyFactory {
private Object targetObject;//目标对象
private BeforeAdvice beforeAdvice;//前置增强
private AfterAdvice afterAdvice;//后置增强
/**
* 用来生成代理对象
* @return
*/
public Object createProxy() {
/*
* 1. 给出三大参数
*/
ClassLoader loader = this.getClass().getClassLoader();
Class[] interfaces = targetObject.getClass().getInterfaces();
InvocationHandler h = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
/*
* 在调用代理对象的方法时会执行这里的内容
*/
// 执行前置增强
if(beforeAdvice != null) {
beforeAdvice.before();
}
Object result = method.invoke(targetObject, args);//执行目标对象的目标方法
// 执行后置增强
if(afterAdvice != null) {
afterAdvice.after();
}
// 返回目标对象的返回值
return result;
}
};
/*
* 2. 得到代理对象
*/
Object proxyObject = Proxy.newProxyInstance(loader, interfaces, h);
return proxyObject;
}
public Object getTargetObject() {
return targetObject;
}
public void setTargetObject(Object targetObject) {
this.targetObject = targetObject;
}
public BeforeAdvice getBeforeAdvice() {
return beforeAdvice;
}
public void setBeforeAdvice(BeforeAdvice beforeAdvice) {
this.beforeAdvice = beforeAdvice;
}
public AfterAdvice getAfterAdvice() {
return afterAdvice;
}
public void setAfterAdvice(AfterAdvice afterAdvice) {
this.afterAdvice = afterAdvice;
}
}
Загрузка кода:git ee.com/go on ah plug ah/max…