Spring的自动装配有三种模式:byType(根据类型),byName(根据名称)、constructor(根据构造函数)。
byType
找到与依赖类型相同的bean注入到另外的bean中,这个过程需要借助setter注入来完成,因此必须存在set方法,否则注入失败。
当xml文件中存在多个相同类型名称不同的实例Bean时,Spring容器依赖注入仍然会失败,因为存在多种适合的选项,Spring容器无法知道该注入那种,此时我们需要为Spring容器提供帮助,指定注入那个Bean实例。可以通过<bean>标签的autowire-candidate设置为false来过滤那些不需要注入的实例Bean
1 | <bean id="userDao" class="com.zejian.spring.springIOC.dao.impl.UserDaoImpl" /> |
byName
将属性名与bean名称进行匹配,如果找到则注入依赖bean。
1 | <bean id="userDao" class="com.zejian.spring.springIOC.dao.impl.UserDaoImpl" /> |
constructor
存在单个实例则优先按类型进行参数匹配(无论名称是否匹配),当存在多个类型相同实例时,按名称优先匹配,如果没有找到对应名称,则注入失败,此时可以使用autowire-candidate=”false” 过滤来解决。
1 | <!--只存在userDao2,userDao3 无法成功注入--> |
@Autowired 可以传递了一个required=false的属性,false指明当userDao实例存在就注入不存就忽略,如果为true,就必须注入,若userDao实例不存在,就抛出异常。由于默认情况下@Autowired是按类型匹配的(byType),如果需要按名称(byName)匹配的话,可以使用@Qualifier注解与@Autowired结合。
1 | public class UserServiceImpl implements UserService { |
byName模式 xml 配置:
1 | <!-- 根据@Qualifier("userDao1")自动识别 --> |
@Resource,默认按 byName模式自动注入。@Resource有两个中重要的属性:name和type。Spring容器对于@Resource注解的name属性解析为bean的名字,type属性则解析为bean的类型。因此使用name属性,则按byName模式的自动注入策略,如果使用type属性则按 byType模式自动注入策略。倘若既不指定name也不指定type属性,Spring容器将通过反射技术默认按byName模式注入。
1 |
|
上述两种自动装配的依赖注入并不适合简单值类型,如int、boolean、long、String以及Enum等,对于这些类型,Spring容器也提供了@Value注入的方式。@Value接收一个String的值,该值指定了将要被注入到内置的java类型属性值,Spring 容器会做好类型转换。一般情况下@Value会与properties文件结合使用。
jdbc.properties文件如下:
1 | jdbc.driver=com.mysql.jdbc.Driver |
利用注解@Value获取jdbc.url和jdbc.username的值,实现如下:
1 | public class UserServiceImpl implements UserService { |
xml配置文件:
1 | <!--基于占位符方式 配置单个properties --> |
@Autowired和@Resource
@Autowired注解是按照类型(byType)装配依赖对象的,但是存在多个类型⼀致的bean,⽆法通过byType注⼊时,就会再使⽤byName来注⼊,如果还是⽆法判断注⼊哪个bean则会UnsatisfiedDependencyException。
@Resource会⾸先按照byName来装配,如果找不到bean,会⾃动byType再找⼀次。
声明Bean注解
Spring 容器通过xml的bean标签配置和java注解两种方式声明的Bean对象。Spring的框架中提供了与@Component注解等效的用于声明bean的三个注解,@Repository 用于对DAO实现类进行标注,@Service 用于对Service实现类进行标注,@Controller 用于对Controller实现类进行标注。同时还可以给定一个bean名称,如果没有提供名称,那么默认情况下就是一个简单的类名(第一个字符小写)变成Bean名称。
1 | //@Component 相同效果 |
xml配置 bean:
1 | <bean id="userService" class="com.zejian.spring.springIOC.service.impl.UserServiceImpl" /> |
@Bean和@Component
都是使用注解定义 Bean。@Bean 是使用 Java 代码装配 Bean,@Component 是自动装配 Bean。
@Component 注解用在类上,表明一个类会作为组件类,并告知Spring要为这个类创建bean,每个类对应一个 Bean。
@Bean 注解用在方法上,表示这个方法会返回一个 Bean。@Bean 需要在配置类中使用,即类上需要加上@Configuration注解。
1 |
|
@Bean 注解更加灵活。当需要将第三方类装配到 Spring 容器中,因为没办法源代码上添加@Component注解,只能使用@Bean 注解的方式,当然也可以使用 xml 的方式。
阅读量