Spring框架基于xml实现自动装配流程详解
学习使我快乐T 人气:0一、基于xml的自动装配之场景模拟:
自动装配:
根据指定的策略,在IOC容器中匹配某一个bean,自动为指定的bean中所依赖的类类型或接口类 型属性赋值
场景模拟
①创建类UserController
public class UserController { private UserService userService; public UserService getUserService() { return userService; } public void setUserService(UserService userService) { this.userService = userService; } public void saveUser() { userService.saveUser(); } }
创建接口UserService
public interface UserService { /** 保存用户信息 */ void saveUser(); }
创建类UserServiceImpl实现接口UserService
public class UserServiceImpl implements UserService { private UserDao userDao; public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void saveUser() { System.out.println("保存成功"); } }
创建接口UserDao
public interface UserDao { /** * 保存用户信息 */ void saveUser(); }
创建类UserDaoImpl实现接口UserDao
public class UserDaoImpl implements UserDao { @Override public void saveUser() { System.out.println("保存成功"); } }
②配置bean
<bean id="userController" class="com.tian.spring.controller.UserController"> <property name="userService" ref="userService"></property> </bean> <bean id="userService" class="com.tian.spring.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"></property> </bean> <bean id="userDao" class="com.tian.spring.dao.impl.UserDaoImpl"></bean>
③测试类:
public class AutowireByXMLTest { @Test public void testAutowire() { ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-autowire-xml.xml"); UserController userController = ioc.getBean(UserController.class); userController.saveUser(); } }
结果:
保存成功
二、基于xml的自动装配之byType
可以通过bean标签中的autowire属性设置自动装配的策略
自动装配的策略:
1.no,default:表示不装配,即bean中的属性不会自动匹配某个bean为属性赋值,此时属性使用默认值
2.byType:根据要赋值的属性的类型,在IOC容器中匹配某个bean,为属性赋值
注意:
(一些用byType进行自动装配的问题,当然不容易见到,这里我也不去演示,知道就可以):
a>若通过类型没有找到任何一个类型匹配的bean,此时不装配,属性使用默认值
b>若通过类型找到了多个类型匹配的bean,此时会抛出异常:NoUniqueBeanDefinitionException
总结:
当使用byType实现自动装配时,IOC容器中有且只有一个类型匹配的bean能够为属性赋值
3.byName:将要赋值的属性的属性名作为bean的id在IOC容器中匹配某个bean,为属性赋值
总结:
当类型匹配的bean有多个时,此时可以使用byName实现自动装配
配置bean
<bean id="userController" class="com.tian.spring.controller.UserController" autowire="byType"> <!-- <property name="userService" ref="userService"></property>--> </bean> <bean id="userService" class="com.tian.spring.service.impl.UserServiceImpl" autowire="byType"> <!-- <property name="userDao" ref="userDao"></property>--> </bean> <bean id="userDao" class="com.tian.spring.dao.impl.UserDaoImpl"></bean>
经过测试发现也是可以进行输出的
保存成功
三、基于xml的自动装配之byName
<bean id="userController" class="com.tian.spring.controller.UserController" autowire="byName"> <!-- <property name="userService" ref="userService"></property>--> </bean> <bean id="userService" class="com.tian.spring.service.impl.UserServiceImpl" autowire="byName"> <!-- <property name="userDao" ref="userDao"></property>--> </bean> <bean id="service" class="com.tian.spring.service.impl.UserServiceImpl" autowire="byName"> <!-- <property name="userDao" ref="userDao"></property>--> </bean> <bean id="userDao" class="com.tian.spring.dao.impl.UserDaoImpl"></bean> <bean id="dao" class="com.tian.spring.dao.impl.UserDaoImpl"></bean>
经过测试发现也是可以进行输出的
保存成功
四、基于注解管理bean之功能分析
@Component:将类标识为普通组件
@Controller:将类标识为控制层组件
@Service:将类标 识为业务层组件
@Repository:将类标识为持久层组件
通过注解+扫描所配置的bean的id,默认值为类的小驼峰,即类的首字母为小写的结果
可以通过标识组件的注解的value属性值设置bean的自定义的id
①创建maven工程,并引入相关依赖
<dependencies> <!-- 基于Maven依赖传递性,导入spring-context依赖即可导入当前所需所有jar包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.23</version> </dependency> <!-- junit测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies>
②创建组件
创建控制层
@Controller("controller") public class UserController { }
创建业务层
UserService接口
@Repository public interface UserDao { }
UserServiceImpl实现类
public class UserDaoImpl implements UserDao { }
创建持久层
UserDao接口
public interface UserDao { }
UserDaoImpl实现类
@Repository public class UserDaoImpl implements UserDao { }
③创建配置文件spring-ioc-annotation.xml
<context:component-scan base-package="com.tian.spring"></context:component-scan>
测试类:
public class IOCByAnnotationTest { @Test public void test() { ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml"); UserController userController = ioc.getBean("controller" ,UserController.class); System.out.println(userController); UserService userService = ioc.getBean("userServiceImpl",UserService.class); System.out.println(userService); UserDao userDao = ioc.getBean("userDaoImpl",UserDao.class); System.out.println(userDao); } }
五、基于注解管理bean之扫描组件
context:exclude-filter:排除扫描
type:设置排除扫描的方式 type="annotation/assignable" annotation:根据注解的类型进行排除,expression需要设置排除的注解的全类名 assignable:根据类的类型进行排除,expression需要设置排除的类的全类名
context:include-filter:包含扫描
注意:需要在context:component-scan标签中设置use-default-filters="false" use-default-filters="true"(默认),所设置的包下所有的类都需要扫描,此时可以使用排除扫描 use-default-filters="false",所设置的包下所有的类都不需要扫描,此时可以使用包含扫描
情况一,最基本的扫描方式:
<context:component-scan base-package="com.tian.spring"></context:component-scan>
情况二:指定要排除的组件
<context:component-scan base-package="com.tian.spring" use-default-filters="false"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
情况三:仅扫描指定组件
<context:component-scan base-package="com.tian.spring" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
六、基于注解的自动装配之@Autowired注解能够标识的位置及其原理和注意事项
@Autowired:实现自动装配功能的注解
1)@Autowired注解能够标识的位置
a>标识在成员变量上,此时不需要设置成员变量的set方法
b>标识在set方法上
c>为当前成员变量赋值的有参构造上
2)@Autowired注解的原理
a>默认通过byType的方式,在IOC容器中通过类型匹配某个bean为属性赋值
b>若有多个类型匹配的bean,此时会自动转换为byName的方式实现自动装配的效果
即将要赋值的属性的属性名作为bean的id匹配某个bean为属性赋值
c>若byType和byName的方式都无法实现自动装配,即IOC容器中有多个类型匹配的bean
且这些bean的id和要赋值的属性的属性名都不一致,此时抛异常:NoUniqueBeanDefinitionException
d>此时可以在要赋值的属性上,添加注解@Qualifier
通过该注解的value属性值,指定某个bean的id,将这个bean为属性赋值
3)注意:
若IOC容器中没有任何一个类型匹配的bean,此时抛出异常NoSuchBeanDefinitionException
在@Autowired注解中有个属性required,默认值为true,要求必须完成自动装配
可以将required设置为false,此时能装配则装配,无法装配则使用属性的默认值
(由于一个类型的bean不可能在IOC容器中配置多次,所以这种情况一般不会出现)
1)@Autowired:实现自动装配功能的注解
方式一:
@Autowired private UserService userService;
方式二:
@Autowired public void setUserService(UserService userService) { this.userService = userService; }
方式三:
@Autowired public UserController(UserService userService) { this.userService = userService; }
加载全部内容