14Spring通过注解配置Bean(2)
下面将对13Spring通过注解配置Bean(1)的中Repository、Service、Controller通过注解方式来建立关联。
<context:component-scan>元素还会自动注册AutowiredAnnotationBeanPostProcessor后置处理器实例,该实例可以自动装配具有@Autowired属性。
- @Autowired注解会自动装配具有兼容类型的单个Bean属性
——构造器,普通字段(即使是非public),一切具有参数的方法都可以应用@Autowired注解
——默认情况下,所有使用@Autowired注解的属性都需要被设置,当Spring找不到匹配的Bean装配属性时,会抛出异常,若某一属性允许不被设置,可以设置@Autowired注解的required属性为false
——默认情况下,当IOC容器里存在多个类型兼容的Bean时,通过类型的自动装配将无法工作,此时可以在@Qualifier注解里提供Bean的名称,Spring允许对方法的入参标注@Qualifier已指定注入Bean的名称
——@Autowired注解也可以应用在数组类型的属性上,此时Spring将会把所有匹配的Bean进行自动装配。
——@Autowired注解也可以应用在集合属性上,此时Spring读取集合的类型信息,然后自动装配所有与之兼容的Bean。
——@Autowired注解用在java.util.Map上时,若该Map的键值为String,那么Spring将自动装配与之Map值类型兼容的Bean,此时ean的名称作为键值
package annotation.repository; public interface UserRepository { void save(); }
package annotation.repository; import annotation.TestObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @Repository public class UserRepositoryImpl implements UserRepository { /** * required = false表示IOC容器中可有可无,否则一定要配置TestObject的bean实例 */ @Autowired(required = false) private TestObject testObject; @Override public void save() { System.out.println("UserRepositoryImpl save"); System.out.println(testObject); } }
package annotation.repository; import org.springframework.stereotype.Repository; /** * Created by jecyhw on 2015/6/19. */ @Repository public class UserJdbcRepository implements UserRepository { @Override public void save() { System.out.println("UserJdbcRepository save"); } }
package annotation.service; import annotation.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @Service public class UserService { //配置userRepository有三种方式 /* @Autowired @Qualifier(value = "userRepositoryImpl") private UserRepository userRepository;*/ /* @Autowired @Qualifier(value = "userRepositoryImpl")*/ private UserRepository userRepository; /* @Autowired @Qualifier(value = "userRepositoryImpl")//当有多个兼容的Bean时,来指定Bean的名称,未指定的话,将会使用名称自动和兼容Bean的名称比较,如果未找到唯一匹配值将会触发多个Bean无法匹配异常 public void setUserRepository( UserRepository userRepository) { this.userRepository = userRepository; }*/ @Autowired public void setUserRepository( @Qualifier(value = "userRepositoryImpl") UserRepository userRepository) { this.userRepository = userRepository; } public void add() { System.out.println("UserService add"); userRepository.save(); } }
package annotation.controller; import annotation.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class UserController { @Autowired private UserService userService; public void execute() { System.out.println("UserController execute"); userService.add(); } }
<?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.xsd"> <!--指定Spring IOC容器扫描的包--> <!--<context:component-scan base-package="annotation"> </context:component-scan>--> <!--可以通过resource-pattern指定扫描的资源--> <!--<context:component-scan base-package="annotation" resource-pattern="repository/*.class"> </context:component-scan>--> <!--context:exclude-filter 子节点指定排除哪些指定表达式的组件--> <!--context:include-filter 子节点指定包含指定表达式的组件,该子节点需要use-default-filters 配个使用--> <context:component-scan base-package="annotation"> <!--annotation表示根据指定注解来包含还是不包含--> <!--<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"></context:exclude-filter>--> <!--<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"></context:include-filter>--> <!--assignable根据指定类名来包含还是不包含--> <!-- <context:exclude-filter type="assignable" expression="annotation.repository.UserRepository"></context:exclude-filter>--> <!--<context:include-filter type="assignable" expression="annotation.repository.UserRepository"></context:include-filter>--> </context:component-scan> </beans>
package annotation; import annotation.controller.UserController; import annotation.repository.UserRepository; import annotation.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("14-1.xml"); // TestObject to = (TestObject) ctx.getBean("testObject"); // System.out.println(to); UserController userController = (UserController) ctx.getBean("userController"); System.out.println(userController); userController.execute(); // UserService userService = (UserService) ctx.getBean("userService"); // System.out.println(userService); // // UserRepository userRepository = (UserRepository) ctx.getBean("userRepository"); // System.out.println(userRepository); } }