使用jdk-Proxy在spring中进行切面

前言

个人兴趣,平时喜欢使用jdk的东西捣鼓东西.以前学spring的时候就对切面这一块乱七八糟的配置整的晕头转向,就想着用干脆直接用jdk的Proxy代理得了,于是就整出了下面这些骚东西…

关于jdk的动态代理

jdk的动态代理核心是Proxy类与InvocationHandler接口,其中Proxy负责生成与调用代理类,InvocationHandler则是实际的执行者,具体原理参见JDK动态代理的实现和原理解析(基于JDK1.7),上代码

1 创建被代理类

// 将会被代理的类就是这家伙,万恶的资本家是也!
public class Aristotle implements People {
	@Override
	public void dieAble() {
		System.out.println("亚里士多德是人");
	}
}

// 在jdk的动态代理中,被代理的类必须实现某个接口,而它,就是那个接口!↙↙↙↙请叫它资本家工会↙↙↙↙
public interface People {
	public void dieAble();
}

2 创建真正的工作者

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

// 这才是真正的执行者,脏活累活都是他干的 ↓↓↓↓↓↓↓↓↓↓↓↓↓
public class DieCheck implements InvocationHandler {
	
	private People people;
	public DieCheck(People dieable) {
		this.people=dieable;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("人会死");
		Object invoke = method.invoke(people, args);
		System.out.println("亚里士多德会死");
		return invoke;
	}
}

3 执行代理

import java.lang.reflect.Proxy;

import com.ddyii.apitest.aspect.domain.Aristotle;
import com.ddyii.apitest.aspect.domain.superclass.DieCheck;
import com.ddyii.apitest.aspect.domain.superclass.People;


public class JDKProxy {
	public static void main(String[] args) {
		// 首先,得有一个无良商人
		People aristotle = new Aristotle();
		// 然后用钱招工,一个可怜的家伙上钩了
		People newInstance = (People) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), aristotle.getClass().getInterfaces(), new DieCheck(aristotle));
		// 血泪工厂working   T_T
		newInstance.dieAble();
	}
}

4 结果,哲学的气息

人会死
亚里士多德是人
亚里士多德会死

在Spring中使用JDK动态代理

Spring搭建那些就省略了…

1 同样是要有个接口,但这次我们叫它"服务",即Service层

package com.keke.service;
// 首先
public interface IUserService {	
	public String getUser(String id);
}

2 代理

package com.keke.service.impl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.stereotype.Service;
import com.keke.service.IUserService;

// 熟悉的配方,熟悉的味道,但这次,不再是万恶的资本家压榨劳动人民,劳动人民站了起来,成了...个体户...^_^
@Service
public class UserService implements InvocationHandler,IUserService{
		
	@Override
	public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
		System.out.println(Arrays.deepToString(params));
		Object invoke = method.invoke(this, params);
		System.out.println("添加日志");
		return invoke;
	}

	@Override
	public String getUser(String id) {
		System.out.println("查询用户");
		return "user";
	}
}

3 执行代理

package com.keke.controller;

import java.lang.reflect.Proxy;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.keke.service.IUserService;
import com.keke.service.impl.UserService;

@RestController
@RequestMapping("user")
public class UserController {

	@Autowired
	IUserService userService;
	
	// 这一步很关键,狸猫换太子,悄悄地把spring bean里面的太子爷换成了自己的小宝宝
	@PostConstruct
	public void init() {
		userService = (IUserService) Proxy.newProxyInstance(UserController.class.getClassLoader(), new Class[] {IUserService.class}, new UserService());
	}
	
	@RequestMapping("getUser")
	public String getUser() {
		return userService.getUser("id");
	}
}

4 执行结果

[id]
查询用户
添加日志

你可能感兴趣的:(java)