spring6.1在java17环境下使用反射

引包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>3.3.4</version>
</dependency>

反射代码

  编写简单的反射方法,如下所示

package com.lw.reflect.cglib;

import com.lw.reflect.UserServiceImpl;
import org.springframework.cglib.proxy.*;

import java.lang.reflect.Method;

public class SpringCglibProxyUtil {

    public static void main(String[] args) {
        // 创建Enhancer对象
        Enhancer enhancer = new Enhancer();
        // 设置Enhancer对象的父类
        enhancer.setSuperclass(UserServiceImpl.class);
        // 设置回调方法
        enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                System.out.println("Before method: " + method.getName());
                // 调用父类(被代理对象)的方法
                Object result = proxy.invokeSuper(obj, args);
                System.out.println("After method: " + method.getName());
                return result;
            }
        }, NoOp.INSTANCE});
        enhancer.setCallbackFilter(method -> {
            if(method.getDeclaringClass().isAssignableFrom(Object.class)){
                return 0;//使用NoOp.INSTANCE
            }
            return 0;
        });
        // 创建代理对象
        UserServiceImpl proxyInstance = (UserServiceImpl) enhancer.create();
        // 调用代理对象的方法
        proxyInstance.showInfo();
    }
}

增加module-info.java

module JavaSEBase {
    requires spring.core;
    requires spring.aop;
    opens com.lw.reflect to spring.core;
}

报错

  如果仅仅是上面配置,那么会报错,报错是 module java.base does not open java.lang to module spring.core

  这是java9引入了模块化导致的,所以需要在启动时在VM options加入如下配置,

 

  如果是其他unnamed模块使用,用如下配置,

--add-opens
java.base/java.lang=ALL-UNNAMED
--add-opens
java.base/java.lang.reflect=ALL-UNNAMED

  如果要打包,就在pom.xml中增加如下配置,

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>3.0.0</version>
      <configuration>
        <argLine>
          --add-opens=java.base/java.lang=ALL-UNNAMED
          --add-opens=java.base/java.lang.reflect=ALL-UNNAMED
        </argLine>
      </configuration>
    </plugin>
  </plugins>
</build>

cglib使用

  如果是cglib的使用,这玩意5年前就没更新了,对java9的模块化是不支持的,我搞不懂spring6.1了怎么还对java9不支持,还要添加--add-opens启动选项。

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

   module-info.java中修改如下,

module JavaSEBase {
    requires cglib;
    requires spring.core;
    requires spring.aop;
    opens com.lw.reflect to spring.core,cglib;
}

  测试代码如下,

package com.lw.reflect.cglib;

import com.lw.reflect.UserServiceImpl;
import net.sf.cglib.proxy.*;

import java.lang.reflect.Method;

public class OriginCglibProxyUtil {
    public static void main(String[] args) {
        // 创建Enhancer对象
        Enhancer enhancer = new Enhancer();
        // 设置Enhancer对象的父类
        enhancer.setSuperclass(UserServiceImpl.class);
        // 设置回调方法
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                System.out.println("Before method: " + method.getName());
                // 调用父类(被代理对象)的方法
                Object result = proxy.invokeSuper(obj, args);
                System.out.println("After method: " + method.getName());
                return result;
            }
        });
        // 创建代理对象
        UserServiceImpl proxyInstance = (UserServiceImpl) enhancer.create();
        // 调用代理对象的方法
        proxyInstance.showInfo();
    }
}

  启动配置项: --add-opens java.base/java.lang=cglib

工程结构

java9引入了module,确实在权限控制上更细了,但因此引入的问题也更多,特别是module-info.java这个文件。

 

posted @ 2024-09-21 21:58  伟衙内  阅读(25)  评论(0编辑  收藏  举报