注:本文章仅用于笔记,不做技术交流。如有繆误,敬请指出,(B站尚硅谷王泽老师笔记整理)
就是newProxyInstance()里面的方法参数
public interface UserDao { public int add(int a,int b); public String update(String id); } public class UserDaoImpl implements UserDao { @Override public int add(int a, int b) { return a+b; } @Override public String update(String id) { return id; } } public class JDKProxy { public static void main(String[] args) { //创建接口实现类代理对象 Class[] interfaces = {UserDao.class}; UserDaoImpl userDao = new UserDaoImpl(); UserDao dao = (UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao)); int result = dao.add(1, 2); System.out.println("result:"+result); } } //创建代理对象代码 class UserDaoProxy implements InvocationHandler { //1 把创建的是谁的代理对象,把谁传递过来 //有参数构造传递 private Object obj; public UserDaoProxy(Object obj) { this.obj = obj; } //增强的逻辑 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //方法之前 System.out.println("方法之前执行...."+method.getName()+" :传递的参 数..."+ Arrays.toString(args)); //被增强的方法执行 Object res = method.invoke(obj, args); //方法之后 System.out.println("方法之后执行...."+obj); return res; } }这个里面就可以看到在method.invoke()对method.getName()进行判断,做相应的方法处理 spring里面对相应的代码进行封装
(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强 (2)语法结构: execution([权限修饰符] [返回类型] [类全路径] 方法名称 ) 举例 1:对包名字 类里面的 add 进行增强 execution(* 包名.方法(…)) 举例 2:对包名字 类里面的所有的方法进行增强 execution(* 包名.* (…))
(1)在 spring 配置文件中,开启注解扫描 xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> //开启注解扫描 <context:component-scan basepackage="包名路径"></context:component-scan> (2)使用注解创建 User 和 UserProxy 对象 在这两个类对象的类上面添加@Component注解 (3)在增强类上面添加注解 @Aspect即UserProxy上面 (被增强类是User)(增强类是UserProxy ) 对有@Aspect注解生成代理对象 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>(1)创建配置类,不需要创建 xml 配置文件 @Configuration @ComponentScan(basePackages = {“包名字”}) @EnableAspectJAutoProxy(proxyTargetClass = true) public class ConfigAop { }
AOP主要是在不改变原来的代码的基础上加入新的功能,主要是动态代理,区分有接口和没有接口的情况 有接口就使用JDK的动态代理 没有接口就使用AspectJ