反射+注解 实现 AOP

108 阅读1分钟
/**
 * @author xyf
 * @date 2021/7/7 11:09
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Aspect {

/*
实现切面的类
 */
public Class type();
}

public interface IAspect {
void before();
void after();
}

public interface IOrder {

void pay(String number, String number2) throws InterruptedException;

void show();
}

public class ObjectFactory {

public static <T> T newInstance(Class<T> clazz) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

	Annotation[] annotations = clazz.getAnnotations();
	LinkedList<IAspect> aspects = new LinkedList<IAspect>();
	// 获取类上 所有的aspect注解 的 附关注点的类
	for (Annotation annotation : annotations) {
		if (annotation instanceof Aspect) {
			Class type = ((Aspect) annotation).type();
			IAspect iAspect = (IAspect) type.getConstructor().newInstance();
			aspects.push(iAspect);
		}
	}

	// 构造 T
	T inst = clazz.getConstructor().newInstance();
	//创建代理
	T t = (T) Proxy.newProxyInstance(
			clazz.getClassLoader(),
			clazz.getInterfaces(),
			new InvocationHandler() {
				@Override
				public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
					aspects.forEach(IAspect::before);
                                         
					Object result = method.invoke(inst, args);
					aspects.forEach(IAspect::after);
					return result;
				}
			}
	);
	return  t;
}

@Test
public void test() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, InterruptedException {
	IOrder order =  ObjectFactory.newInstance(Order.class);
	order.pay("1111", "22222");
	order.show();
}
}

@Aspect(type = TimeUsageAspect.class)
public class Order implements IOrder {

int state = 0;

@Override
public void pay(String number,String number2) throws InterruptedException {
	Thread.sleep(50); // 模拟需要耗费时间
	this.state = 1;
	System.out.println("输入参数 1"+number);
	System.out.println("输入参数 1"+number2);
}

@Override
public void show() {

	System.out.println("order status:" + this.state);
}

}

public class TimeUsageAspect implements IAspect {

long start;

@Override
public void before() {
    start = System.currentTimeMillis();
}

@Override
public void after() {
    long usage = System.currentTimeMillis() - start;
    System.out.format("time usage : %dms\n", usage);
}
}