java - 添加自定义 beanpostprocessor 并尝试获取属于类的 bean 时,没有符合条件的 bean 类型异常
问题描述
我正在学习 java 中的代理使用,并想记录方法执行的时间。
所有这些组件都放在 com.example.testproxyproject 包中。
我有 Order 接口,由 OrderImpl 类实现
命令:
@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 类中使用它
自定义Bean处理器:
@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());
}
}
在演示应用程序中,我测试了我的自定义 beanpostprocessor
@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 类,我会得到这个异常
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)
解决方案
这正是您将依赖项声明为接口而不是实现类的原因:您将原始 bean 替换OrderImpl
为不再是OrderImpl
. 其他类型的建议也会发生完全相同的事情。
推荐阅读
- excel - 如何在 VBA excel 宏中实现单元格选择
- rust - 如何让struct持有一个线程并在它超出范围后立即销毁线程
- java - 在使用 switch 语句的文本菜单上更改输出
- javascript - 全部完成后的 Javascript 回调
- vue.js - Vue 路由中的 beforeEnter 不适用于子路由
- routes - IONIC 4 - 路由导航
- android - Android ARM C++异常调试
- javascript - 手机中的按下行为 Ionic / Angular / Cordova App
- python - 两个文件的区别
- ios - 尾部截断不适用于自定义 Xamarin.iOS 表格视图单元格