基于XML的自动装配
自动装配:根据指定的策略,在 IOC 容器中匹配某一个 bean ,自动为指定的 bean 中所依赖的类类型或接口类 型属性赋值
三层架构
实体类包(pojo/entity/bean):专门存放和数据库对应的实体类和一些VO对象;
数据库访问包(dao/mapper):专门存放对数据库不同表格CURD方法封装的一些类;-->A-
服务包(service): 专门存放对数据进行业务逻辑预算的一些类-->B
Controller: 控制层------C
A是根包,A层创建实体类(包含详细方法)和接口
B是中转包,创建A的对象,并在B自定义方法中调用A的方法(有接口)
C是控制包,创建B的对象,调用B的方法(无接口)
Bean的自动装配
根据指定的策略,在IOC容器中匹配相应的bean,可自动为bean中的类类型属性或接口类型属性赋值(字面型不行)
<!--<bean id="userControl" class="com.wjj.spring.controller.UserControl" autowire="byType">
<property name="userService" ref="userService"></property>
</bean>
-->
简化后
<bean class="com.wjj.spring.controller.UserControl" autowire="byType">
</bean>
Bean注解---组件注解
@Component:将类标识为普通组件
@Controller:将类标识为控制层组件
@Service:将类标识为业务层组件
@Repository:将类标识为持久层组件
<!--扫描组件 -->
<context:component-scan base-package="com.wjj.spring" use-default-filters="true">
@Controller,@Service,@Repository三个注解是在@Component的基础上延展出来的,本质上没有区别,只是为了便于开发人员区分。
注解作用:可以将扫描的包下的含有注解的类作为主键管理,即在beans中有了含有注解的类的bean对象
不扫描某个注解
context:exclude-filter-->排除扫描
两种扫描方式
type=annotation/assignable
annotation-->根据注解的类型进行管理(使用较多)
assignable-->根据类的类型进行管理
expression--->根据需要管理的类/注解的全类名
<context:component-scan base-package="com.wjj.spring">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="assignable" expression="com.wjj.spring.controller.UserController"/>
</context:component-scan>
扫描某个注解
<context:include-filter:包含扫描 type(use-default-filters="false")才能开启;
注意:需要在context :component - scan标签中设置use -default - filters= "false”
use-default - filters="true" (默认),所设置的包下所有的类都需要扫描,
此时可以使用排除扫描 use -default -filters= "false",
所设置的包下所有的类都不需要扫描,此时可以使用包含扫描
<context:component-scan base-package="com.wjj.spring" use-default-filters="false">
<context:include-filter type="assignable" expression="com.wjj.spring.controller.UserController"/>
</context:component-scan>
通过注解加扫描所配置bean的id,默认值为类的小驼峰
自定义id:通过标识组件的注解,来设置id;
基于注解的自动装配
@Autowired-->实现自动装配功能的注解
@Autowired注解能够标识的位置
1.能够标识在成员变量之上,此时不需要成员变量的set方法
2.能够标识在set方法之上
3.标识在成员变量赋值的有参构造上
/** 法一: @Autowired
* private UserService userService;
*/
/**法二:
* private UserService userService;
*
* @Autowired
public void setUserService(UserService userService) {
* this.userService = userService;
* }
*/
//法三
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
public void saveUser() {
userService.saveUser();
}
@AUtowried注解装配的原理
1. 默认通过byType的方式,在IOC容器中通过类型匹配为属性赋值
2.若有多个类型匹配的bean,此时会自动转换成byName的方式实现自动装配的效果,
即将要赋值的属性的属性名作为bean的id匹配某个bean为属性赋值
3.若byTpye和byName的方式都无法实现自动装配,即IOC容器中有多个类型匹配的bean
且这些bean的id和要赋值的属性的属性名都不一致,此时抛异常:NoUniqueBeanDefinitionException;
4.此时可以在要赋值的属性上,添加一个@Qualifier
通过该注解的value属性值,指定某个bean的id,将这个bean为属性赋值
@Autowired
@Qualifier("userServiceImpl")
private UserService userService;
public void saveUser() {
userService.saveUser();
}
@Autowired,自动装配,若没有找到任何一个bean进行装配,会报
NoSuchBeanDefinitionException的错误,而基于XML的找不到会使用默认值null,则报
NullPointException,若将@Autowired(required=false 默认为true),则也·报空指针异常