Spring可以从classPath下自动扫描,侦测和实例化具有特定注解的组件;
特定的组件包括:
1.@Component:基本注解,标识一个首Spring管理得组件
2.@Respository:标识持久化组件
3.@Service:标识服务层组件
4.@Controller:标识表现层组件
Spring有默认的命名策略,即第一个字母小写,也可以在注解中通过value属性命名。
在组件上使用注解后需要在Spring配置文件中声明<Context:component-scan>自动扫描包路径下的组件
举例:
UserAction——UserService——UserDao
xml:
base-package:要扫描包的全路径
<?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">
<!-- 配置自动扫描的包: 需要加入 aop 对应的 jar 包 -->
<context:component-scan base-package="com.atguigu.spring.annotation"></context:component-scan>
</beans>
输出:
需要注意的是@Autowired可以标注在属性上也可以标注在set方法上,默认情况下所有使用@Autowired的注解都需要被设置,当Spring找不到匹配的bean装配属性时,会抛异常,若某一属性允许不被设置需要将@Autowired的required属性设置为false;
此外当IOC容器中存在多个同类型的Bean时,通过类型进行的自动装配将会好不到对应的bean,此时可以在@Qualifier注解里提供Bean的名称(Spring允许对set方法的入参设置@Qualifier已指定注入的Bean名称)
例如这种情况:
两个imp实现同一类BaseService
编写 controller:
Main方法:
运行时错误:
修改Controller为@Autowired 添加 @Qualifier属性 指定要配置的bean,注意默认的命名规则
或者:
输出:
下面在说说泛型依赖注入:
这个很简单,结构图如下:
BaseDao:
package com.atguigu.spring.annotation.generic;
public class BaseDao<T> {
public void save(T entity){
System.out.println("Save:" + entity);
}
}
BaseService:
BaseService 注入BaseDao
package com.atguigu.spring.annotation.generic;
import org.springframework.beans.factory.annotation.Autowired;
public class BaseService<T> {
@Autowired
private BaseDao<T> dao;
public void addNew(T entity){
System.out.println("addNew by " + dao);
dao.save(entity);
}
}
UserDao继承BaseDao:
package com.atguigu.spring.annotation.generic;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao extends BaseDao<User>{
}
UserService 继承BaseService
package com.atguigu.spring.annotation.generic;
import org.springframework.stereotype.Service;
//若注解没有指定 bean 的 id, 则类名第一个字母小写即为 bean 的 id
@Service
public class UserService extends BaseService<User>{
}
Main:
UserService userService = (UserService) ctx.getBean("userService");
userService.addNew(new User());
输出: