内部Bean
我们刚才是先创建userDao对象,再由userService对userDao对象进行引用…我们还有另一种思维:先创建userService,发现userService需要userDao的属性,再创建userDao…我们来看看这种思维方式是怎么配置的:
applicationContext.xml配置文件:property节点内置bean节点
<!-- 1.创建userService,看到有userDao这个属性 2.而userDao这个属性又是一个对象 3.在property属性下又内置了一个bean 4.创建userDao --> <bean id="userService" class="UserService"> <property name="userDao"> <bean id="userDao" class="UserDao"/> </property> </bean>
- 测试
我们发现这种思维方式和服务器访问的执行顺序是一样的,但是如果userDao要多次被其他service使用的话,就要多次配置了…
p 名称空间注入属性值
p名称控件这种方式其实就是set方法的一种优化,优化了配置而已…p名称空间这个内容需要在Spring3版本以上才能使用…我们来看看:
applicationContext.xml配置文件:使用p名称空间
<bean id="userDao" class="UserDao"/> <!--不用写property节点了,直接使用p名称空间--> <bean id="userService" class="UserService" p:userDao-ref="userDao"/>
- 测试
自动装配
Spring还提供了自动装配的功能,能够非常简化我们的配置
自动装载默认是不打开的,自动装配常用的可分为两种:
- 根据名字来装配
- 根据类型类装配
XML配置根据名字
applicationContext.xml配置文件:使用自动装配,根据名字
<bean id="userDao" class="UserDao"/> <!-- 1.通过名字来自动装配 2.发现userService中有个叫userDao的属性 3.看看IOC容器中没有叫userDao的对象 4.如果有,就装配进去 --> <bean id="userService" class="UserService" autowire="byName"/>
- 测试
XML配置根据类型
applicationContext.xml配置文件:使用自动装配,根据类型
值得注意的是:如果使用了根据类型来自动装配,那么在IOC容器中只能有一个这样的类型,否则就会报错!
<bean id="userDao" class="UserDao"/> <!-- 1.通过名字来自动装配 2.发现userService中有个叫userDao的属性 3.看看IOC容器UserDao类型的对象 4.如果有,就装配进去 --> <bean id="userService" class="UserService" autowire="byType"/>
- 测试:
我们这只是测试两个对象之间的依赖关系,如果我们有很多对象,我们也可以使用默认自动分配
使用注解来实现自动装配
@Autowired注解来实现自动装配:
- 可以在构造器上修饰
- 也可以在setter方法上修饰
- 来自java的@Inject的和@AutoWired有相同的功能
如果没有匹配到bean,又为了避免异常的出现,我们可以使用required属性上设置为false。【谨慎对待】
- 测试代码
@Component public class UserService { private UserDao userDao ; @Autowired public void setUserDao(UserDao userDao) { this.userDao = userDao; } }
顺利拿到userDao的引用
使用JavaConfig配置类实现对象依赖
在有两种方法(但我测试不出来,如果会的请在评论去告诉我.….)
- 第一种(测试不出来)
import org.springframework.context.annotation.Bean; @org.springframework.context.annotation.Configuration public class Configuration { @Bean() public UserDao userDao() { return new UserDao(); } @Bean public UserService userService() { //直接调用@bean的方法 return new UserService(userDao()); } }
- 第二种(测试不出来)
import org.springframework.context.annotation.Bean; @org.springframework.context.annotation.Configuration public class Configuration { @Bean() public UserDao userDao() { return new UserDao(); } @Bean public UserService userService(UserDao userDao) { //通过构造函数依赖注入 return new UserService(userDao); } }
- 如果我直接通过构造器传入的话,那么报错了
import org.springframework.beans.factory.annotation.Autowire; import org.springframework.context.annotation.Bean; @org.springframework.context.annotation.Configuration public class Configuration { @Bean() public UserDao userDao() { return new UserDao(); } @Bean(autowire = Autowire.BY_TYPE) public UserService userService(UserDao userDao) { return new UserService(userDao); } }
- 我测试中只有通过这种方法才能拿到userDao的引用。
public class Configuration { @Bean() public UserDao userDao() { return new UserDao(); } @Bean(autowire = Autowire.BY_TYPE) public UserService userService() { return new UserService(userDao()); } }
当然了,最简单直观的方法还有一种:在UserService中加入setUser()方法,那么只要set进去就行了..
- UserService
public class UserService { private UserDao userDao ; public UserService() { } public UserService(UserDao userDao) { } public void setUserDao(UserDao userDao) { this.userDao = userDao; } }
- Config
import org.springframework.context.annotation.Bean; @org.springframework.context.annotation.Configuration public class Config1 { @Bean(name = "userDao") public UserDao userDao() { return new UserDao(); } @Bean(name="userService") public UserService userService() { UserService userService = new UserService(); userService.setUserDao(userDao()); return userService; } }
最后
扩展阅读: