添加自定义 beanpostprocessor 并尝试获取 类 的 bean 时,没有类型异常的合格 bean

No qualifying bean of type exception when added custom beanpostprocessor and trying to get beans that are classes

我正在学习 java 中的代理用法,并希望记录方法的执行时间。

所有这些组件都放在 com.example.testproxyproject 包中。

我有 OrderImpl 实现的 Order 接口 class

订单:

@Component
public interface Order {
    String getName();
    String getVector();
    void setName(String name);
    void setVector(String vector);
}

OrderImpl 只覆盖那些方法,不添加新的期望注释

OrderImpl:

@Component
public class OrderImpl implements Order {
    private String name;
    private String vector;
    @Time
    @Override
    public String getName() {
        return name;
    }
    @Override
    public String getVector() {
        return vector;
    }
    @Time
    @Override
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void setVector(String vector) {
       this.vector = vector;
    }
}

时间标注很简单

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Time {
}

对于代理,我有自定义调用处理程序,我在其中测量标有时间注释的方法执行时间

public class CustomInvokeHandler implements InvocationHandler {
    private Object object;
    private List<Method> methods;
    public CustomInvokeHandler(Object object,List<Method> methods){
        this.object = object;
        this.methods = methods;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long timeBeforeInvoking = System.nanoTime();
        Object result = method.invoke(object,args);
        if(methods.stream().anyMatch(listMethod->listMethod.getName().equals(method.getName()))) {
            System.out.println(System.nanoTime()-timeBeforeInvoking);
        }
        return result;
    }
}

我在beanPostProcessor中使用它class

CustomBeanProcessor:

@Component
public class CustomBeanProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> beanClass = bean.getClass();
        if (beanClass.getInterfaces().length == 0) return bean;
        return Proxy.newProxyInstance(beanClass.getClassLoader(), beanClass.getInterfaces(), new CustomInvokeHandler(bean, getAnnotatedMethods(bean.getClass().getMethods(), Time.class)));
    }
    public <T extends Annotation>List<Method> getAnnotatedMethods(Method[] methods, Class<T> annotation){
        return Stream.of(methods).filter(method-> method.isAnnotationPresent(annotation)).collect(Collectors.toList());
    }
}

在演示应用程序中,我测试了我的自定义 bean 后处理器

@Configuration
@ComponentScan("com.example.testproxyproject")
public class DemoApplication {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =new AnnotationConfigApplicationContext(DemoApplication.class);
        Order order = context.getBean(Order.class);
        order.setName("new Name");
        System.out.println(order.getName());
    }
}

结果:

当我 运行 它正常工作时,但是如果我将需要的 bean 更改为 OrderImpl class 我将得到这个异常

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.testproxyproject.OrderImpl' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1172)
    at com.example.testproxyproject.DemoApplication.main(DemoApplication.java:12)

这正是为什么将依赖项声明为接口而不是实现的原因class:您替换了原始 bean,即 OrderImpl,使用不再是 OrderImpl 的包装(代理)版本。其他类型的建议也会发生完全相同的事情。