spring中使用@Autowired实现自动装配流程分析

@Autowired注解能够高效的帮助我们实现依赖注入,当然,前提是存在对应的bean已经添加进我们的ioc容器中。

我们从一个简易的Controller类着手,顺便回忆一下springMVC的部分知识。
在我的AccountController类中,类名标注了@Controller,说明该类会以控制器组件,加入到容器中,类和方法上都有@RequestMapping注解,那么我就可以通过/account/findAll/account/saveAccount请求路径来响应对应的请求。此处忽略了springMVC的相关配置信息,不清楚的可以查看之前的内容。很明显,这里的findAll方法,我们是想模拟查询所有账户信息的请求,Controller需要对应Service组件,Service又需要对应的Dao组件。传统方式下,我们需要自己new一个对象出来,而spring非常高效的帮助我们完成了这一任务,而且完成的非常优雅。

@Controller
@RequestMapping("/account")
public class AccountController {

    @Autowired
    private AccountService accountService;

    @RequestMapping("/findAll")
    public String findAll(Model model){
        System.out.println("表现层:查询所有账户 findAll...");
        List<Account> accounts = accountService.findAll();
        model.addAttribute("accountList",accounts);
        return "account";
    }
    @RequestMapping("/saveAccount")
    public void saveAccount(Account account, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("表现层:保存当前账户 saveAccount...");
        accountService.saveAccount(account);
        request.getRequestDispatcher("findAll").forward(request,response);
    }
}

不难想象,我的AccountService 类上肯定是标注了@Service注解的,只要spring配置了对应的包扫描,那么web服务在启动后,会将标注有@Service@Repository@Component注解的类,都加入到ioc容器中,默认索引名为对应类的首字母小写。这里没有提到@Controller,该注解的所有类,一般交给springMVC处理。配置包扫描时多配置一个includeexclude可以实现对应的包含或忽略。
扫描所有组件后,还会注入对应组件的相关依赖。例如这里的AccountController 组件中,有AccountService 相关的依赖,就需要在后者加入到ioc容器中,继而注入对应依赖的引用。
①先根据类型进行查找,查找ioc容器中是否有类型为AccountService的组件,如果存在多个(相关的 接口/类 被 实现/继承),则需要继续根据对应的变量名继续查找。如果我的容器中,只有一个AccountService类型的组件,那么根据类型查找即可完成依赖注入。
②如果同一类型存在多个,则继续通过变量名的方式继续查找。前面提到了,默认的索引名为对应类的首字母小写格式。AccountService在容器中存的名字记为accountService,如果有一个扩展的类,继承自AccountService,它的类名为AccountServiceExt,则它在容器中的名字为accountServiceExt。
③这里的private AccountService accountService变量名,我刚好取的和容器中的名字一样,如果我简化成了as,那当容器中存在多个同类型的组件时,是无法找到唯一锁定的组件注入的,这是我们可以在该属性的上方添加 @Qualifier("accountService")注解,这样可以保证在根据变量名查找的时候,用accountService。
④如果不严格要求对应属性必须被注入,比如这里的accountService我可以让它为null,那么需要设置 @Autowired(required = false),这里需要注意的是,required的默认只为true,表示当标注了@Autowired在注入时没有查到唯一对应的组件时,系统报错;另一个需要注意的是required为该注解的一个属性,不要单独拿出来再当一个注解用,会报错的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章