这是service接口public interface AccountService {
public List<Account> findAll();
}这是service接口的实现类@Service("accountService")
public class AccountServiceImpl implements AccountService {
@Autowired
AccountDao accountDao;
@Override
public List<Account> findAll() {
System.out.println("业务层,查询所有账户信息");
return accountDao.findAll();
}
}
这是controller方法@Controller
@RequestMapping("/account")
public class AccountController {
@Autowired
private AccountServiceImpl accountService1;
@RequestMapping("/findAll")
public String findAll(){
System.out.println("表现层--AccountController.findAll()"); List<Account> list = accountService1.findAll();
for(Account a:list){
System.out.println(a);
}
return "success";
}
}在spring中对service的实现类(AccountServiceImpl)进行声明式事务控制,报错,报错核心信息是
Bean named 'accountService' is expected to be of type 'com.service.impl.AccountServiceImpl' but was actually of type 'com.sun.proxy.$Proxy24'
找到原因是spring的事务控制是对AccountServiceImpl进行基于接口的动态代理,将controller中的自动注入类型改为@Autowired
private AccountService accountService1;即可。那么我就很奇怪,动态代理的原对象肯定也是存在的,为什么自动注入原对象类型会报错呢?
而且报错的信息除了注入失败以外,最主要的还是spring容器中id为accountService的bean类型本应该为AccountServiceImpl类型。spring是怎么知道bean对象原本类型的?
public List<Account> findAll();
}这是service接口的实现类@Service("accountService")
public class AccountServiceImpl implements AccountService {
@Autowired
AccountDao accountDao;
@Override
public List<Account> findAll() {
System.out.println("业务层,查询所有账户信息");
return accountDao.findAll();
}
}
这是controller方法@Controller
@RequestMapping("/account")
public class AccountController {
@Autowired
private AccountServiceImpl accountService1;
@RequestMapping("/findAll")
public String findAll(){
System.out.println("表现层--AccountController.findAll()"); List<Account> list = accountService1.findAll();
for(Account a:list){
System.out.println(a);
}
return "success";
}
}在spring中对service的实现类(AccountServiceImpl)进行声明式事务控制,报错,报错核心信息是
Bean named 'accountService' is expected to be of type 'com.service.impl.AccountServiceImpl' but was actually of type 'com.sun.proxy.$Proxy24'
找到原因是spring的事务控制是对AccountServiceImpl进行基于接口的动态代理,将controller中的自动注入类型改为@Autowired
private AccountService accountService1;即可。那么我就很奇怪,动态代理的原对象肯定也是存在的,为什么自动注入原对象类型会报错呢?
而且报错的信息除了注入失败以外,最主要的还是spring容器中id为accountService的bean类型本应该为AccountServiceImpl类型。spring是怎么知道bean对象原本类型的?
@Autowired
private AccountService accountService
JDK动态代理的原理是根据定义好的规则,用传入的接口创建一个新类,所以只能用接口引用指向代理,而不能用传入的类引用执行动态类。
例如是这个格式:
public class $Proxy1 extends Proxy implements 传入的接口{}
如果想直接注入实现类的话,可以配置 <aop:aspectj-autoproxy proxy-target-class="true"/> 使用cglib代理;
cglib采用的是用创建一个继承实现类的子类