曾经在做.net项目的时候有使用autofac等做ioc,但是学习了Spring后,发现它的依赖注入在使用上也是如此简单。依赖注入分为属性注入和构造注入,我们的目的是在SpringMvc下整合SpringIOC,并且要通过注解的方式注入bean,这样的过程在spring中我们仅需要增加几行的xml注释即可实现。往下看:
1.首先创建我们的应用场景,增加User类:
public class User {
private Integer id;
private String userName;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Override
public String toString(){
return "User{id:" + id + ",userName:"+ this.userName + "}";
}
}
同时,我们增加一下几个类:
@Repository
public class BaseDao<T> {
public void save(T entity){
System.out.println("Save:" + entity);
}
}
@Service
public class BaseService<T,D extends BaseDao<T>> {
private D dao;
}
@Repository
public class UserDao extends BaseDao<User> {
}
@Service
public class UserService extends BaseService<User,UserDao>{
@Autowired
private UserDao userDao;
public void save(User entity){
userDao.save(entity);
}
}
@Controller
@RequestMapping("user")
public class UserAction{
@Autowired
private UserService userService;
@RequestMapping("/save")
public String save(Map<String,Object> map){
User entity= new User();
entity.setId(1);
entity.setUserName("admin");
userService.save(entity);
map.put("user", entity);
return "success";
}
}
这样以来,我们的场景就搭好了,基础代码非常简单,那么我们的目的是要通过访问 http://localhost:8080/SpringMvcTest/user/save 来调用Controller中的save方法。
2.我们的web.xml文件中,增加如下配置:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-common.xml</param-value>
</context-param>
可以看到,我们又增加了一个spring-common.xml文件。
3.在src目录下,我们增加配置文件spring-common.xml。
<!--?xml version="1.0" encoding="UTF-8"?-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
" xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"></beans>
<context:component-scan base-package="com.springmvc">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller">
<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice">
</context:exclude-filter></context:exclude-filter></context:component-scan>
注意这里是exclude-filter。也就是说在spring的扫描中去除掉了对Controller的扫描。
注:context:component-scan该标签意味着spring会扫描com.springmvc包下面的所有相关类。相关类是指具有以下字样的注解:
@Component: 基本注解, 标识了一个受 Spring 管理的组件
@Respository: 标识持久层组件
@Service: 标识服务层(业务层)组件
@Controller: 标识表现层组件
标注了如上注解的类都是受Spring管辖的,而context:exclude-filter标签则排除了@Controller,因为我们要在后面单独对他扫描。
4.在SpringMvc中进行一些配置,防止SpringMVC和SpringIOC对同一个对象的管理重合。修改我们之前src/springmvc.xml的自动扫描包配置:
<context:component-scan base-package="com.springmvc">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller">
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice">
</context:include-filter></context:include-filter></context:component-scan>
注意这里是include-filter。在SpringMvc中,增加了对Controller的扫描。
解释一下:很多配置中一般都会把spring-common.xml和springmvc.xml进行分开配置,这样各司其职,显得更加的清晰。如果我们的Controller都在一个包中,那么springmvc只要扫描Controller的包就可以了,在base-package中直接配置到Controller目录上面,而spring-common只要扫描其他包中的类就可以了。在spring-common的配置也是一样的道理,要去掉Controller包的扫描,防止重复管理。
那么到这里我们的配置就已经完成了,可以发现配置起来是非常简洁的。这时当我们运行项目,我们可以看到方法被正确执行了。