我正在尝试一个简单的例子 目标 点阵
但我不知道,我在这里缺少什么。面临以下错误。
BeanNotOfRequiredTypeException: 名为'fooDao'的Bean预期类型为'com.openource.kms.FooDao',但实际上类型为'com.openource.kms.$Proxy19'。
富道班
package com.opensource.kms;
import org.springframework.stereotype.Component;
interface BarDao {
String m();
}
@Component
public class FooDao implements BarDao {
public String m() {
System.out.println("implementation of m");
return "This is return value";
}
}
外观类
package com.opensource.kms;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class SecurityService {
@Pointcut("target(com.opensource.kms.FooDao)")
public void myPointCut() {}
@Before("myPointCut()")
public void beforeMethod() {
System.out.println("beforeMethod");
}
}
配置类
package com.opensource.kms;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.opensource.kms")
public class JavaConfig {
}
MainApp类
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
FooDao ob = ctx.getBean("fooDao", FooDao.class);
System.out.println("data -> "+ob.m());
ctx.close();
谁能帮我一下,不知道上面的代码中我需要更新哪些步骤才能使用目标代号。
Spring默认为目标类使用JDK动态代理。
在Java内部,代理是使用接口创建的。
public class DebugProxy implements java.lang.reflect.InvocationHandler {
private Object obj;
public static Object newInstance(Object obj) {
return java.lang.reflect.Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new DebugProxy(obj));
}
private DebugProxy(Object obj) {
this.obj = obj;
}
}
这里obj是你的目标类==FooDao。它只有一个接口BarDao。
参考文献 https:/docs.oracle.comjavase8docstechnotesguidesreflectionproxy.html。
对于你的类FooDao将基于BarDao接口创建代理实例,因为它是唯一的接口。
当你调用
FooDao ob = ctx.getBean("fooDao", FooDao.class);
由于使用了aop代理,spring容器中不会有FooDao类的bean。因为默认情况下,Bean的名字是取自类,所以名字是一样的。但是对象将不再是FooDao。它将是由你的接口BarDao创建的spring代理对象。
这就是为什么如果你把FooDao.class -> BarDao.class改为FooDao.class,一切都会好起来。
BarDao ob = ctx.getBean("fooDao", BarDao.class);