Spring深入浅出(三)XML方式以及注解的方式操作IOC
在日常的开发过程中,我们把程序分为3层:Controller层,Service层,DAO层。Controller类似于Servlet,也就是MVC中的控制层。
调用的顺序是:
Controller层调用Service层,Service层调用DAO层,并且Service层和DAO层为接口(符合Java开发的面向接口编程),是一个典型的MVC模式。
基于xml配置方式
步骤:
1、创建一个Controller类,Service接口,Service的实现类,DAO的接口以及DAO的实现类
1 //Controller类 2 public class UserController { 3 4 private UserService userService; 5 6 public UserService getUserService() { 7 return userService; 8 } 9 10 public void setUserService(UserService userService) { 11 this.userService = userService; 12 } 13 14 public User getUserById(int id){ 15 return userService.getUserById(id); 16 } 17 } 18 //Service接口 19 public interface UserService { 20 public User getUserById(int id); 21 } 22 //Service的实现类 23 public class UserServiceImpl implements UserService{ 24 25 private UserDAO userDAO; 26 27 public UserDAO getUserDAO() { 28 return userDAO; 29 } 30 31 public void setUserDAO(UserDAO userDAO) { 32 this.userDAO = userDAO; 33 } 34 35 @Override 36 public User getUserById(int id) { 37 // TODO Auto-generated method stub 38 return userDAO.getUserById(id); 39 } 40 41 } 42 //DAO接口 43 public interface UserDAO { 44 public User getUserById(int id); 45 } 46 47 //DAO的实现类 48 public class UserDAOImpl implements UserDAO{ 49 50 private static Map<Integer,User> users; 51 52 static{ 53 users = new HashMap<Integer,User>(); 54 users.put(1, new User(1, "张三")); 55 users.put(2, new User(2, "李四")); 56 users.put(3, new User(3, "王五")); 57 } 58 59 @Override 60 public User getUserById(int id) { 61 // TODO Auto-generated method stub 62 return users.get(id); 63 } 64 65 }
2、创建一个实体类
public class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public User(int id, String name) { super(); this.id = id; this.name = name; } public User() { super(); } }
3.在spring的配置文件中配置Controller,Service,DAO三层,并完成依赖注入。
说明:由上面的代码可以看出来,在Controller中有Service属性,在Service中有DAO属性,在DAO中没有任何属性,因此在DAO中不需要依赖注入,在Service中需要注入DAO,在Controller中需要注入Service。
<?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"> <!-- 配置Controller层 --> <bean id="userController" class="com.test.controller.UserController"> <property name="userService" ref="userService"></property> </bean> <!-- 配置Service层 --> <bean id="userService" class="com.test.service.impl.UserServiceImpl"> <property name="userDAO" ref="userDAO"></property> </bean> <!-- 配置DAO层 --> <bean id="userDAO" class="com.test.dao.impl.UserDAOImpl"></bean> </beans>
4、测试,查看结果
public class Test { public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserController userController = (UserController) applicationContext.getBean("userController"); User user = userController.getUserById(1); System.out.println(user); } }
基于注解的方式
上述描述是在配置文件中进行注入,而实际开发中,最常用的是使用基于注解的方式来架构分层。
步骤:
第一步:修改配置文件,将UserController,UserService,UserDAO类扫描到IOC容器中。
第二步:在类中设置注解完成依赖注入。
IOC中常用的四种注解:@Controller @Service @Repository @Component
这四种注解在效果上没有任何区别,在编码过程中可以随意使用其中的任意一个。
但是程序员在开发过程中为了区分类,一般选择使用@Controller,@Service,@Repository分别去表示Controller层,Service层和DAO层。这也就成了一种规范。
第三步:编写测试用例,进行测试。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 将类扫描到IOC容器中,这样好使用注解 可以使用精确到包,也可以精确到类 常用包扫描器,这样可以做到扫描包以及子包下的所有类,方便快捷 --> <context:component-scan base-package="com.test"/> </beans>
/** *添加注解 */ @Controller //Controller层的注解,表示该类作为一个控制器。 public class UserController { @Autowired //自动注入的注解 private UserService userService; public User getUserById(int id){ return userService.getUserById(id); } } @Service //Service层的注解,表示该类是业务层。 public class UserServiceImpl implements UserService{ @Autowired private UserDAO userDAO; @Override public User getUserById(int id) { // TODO Auto-generated method stub return userDAO.getUserById(id); } } @Repository //DAO层的注解,表示该类是数据接口层 public class UserDAOImpl implements UserDAO{ private static Map<Integer,User> users; static{ users = new HashMap<Integer,User>(); users.put(1, new User(1, "张三")); users.put(2, new User(2, "李四")); users.put(3, new User(3, "王五")); } @Override public User getUserById(int id) { // TODO Auto-generated method stub return users.get(id); } }
注意:IOC容器自动完成装载(Autowired),默认是byType的方式。
自动装载除了byType的方式,还可以使用byName的方式,使用byName的方式,需要结合@Qualifier注解一起使用。
例如:
/** *byName的方式,是通过属性名去匹配对应bean的id属性值 *在类中添加注解时,已经设置了默认的id,即类名首字母小写其余默认。 * *我们也可以手动设置ID值,写法:@Service("ID值") */ @Service("myUserService") public class UserServiceImpl implements UserService{ @Autowired private UserDAO userDAO; @Override public User getUserById(int id) { // TODO Auto-generated method stub return userDAO.getUserById(id); } } @Controller public class UserController { //@Qualifier中的值必须和Service的ID值一致。 @Autowired() @Qualifier("userService") private UserService userService; public User getUserById(int id){ return userService.getUserById(id); } }