持续学习&持续更新中…
守破离
如果bean对象的创建过程比较复杂,就可以使用@Bean代替@Component
applicationContext.xml:
<?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 https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 没有配置: <bean id="dog" class="programmer.lp.domain.Dog"/> --> <context:component-scan base-package="programmer.lp"/> </beans>
Dog:
// 没有配置@Component public class Dog { private String name; private String nickName; public Dog() { } // ... }
BeanConfiguration:
@Configuration public class BeanConfiguration { @Bean public Dog dog() { return new Dog(); } }
测试:
@Test public void testPerson() { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); Dog dog = ctx.getBean("dog", Dog.class); System.out.println(dog); }
@Configuration public class BeanConfiguration { @Bean("babyDog") public Dog dog() { return new Dog(); } }
@Test public void testPerson() { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); Dog dog = ctx.getBean("babyDog", Dog.class); System.out.println(dog); }
核心思想:要想使用@Autowired自动注入某个对象,就必须确保这个对象存在于IoC容器中,必须被容器所管理。
例子:
@Component public class Food { // ... }
这里Human给food属性使用了@Autowired
public class Human { private Food food; @Autowired public void setFood(Food food) { this.food = food; } }
@Configuration public class BeanConfiguration { @Bean public Human human() { return new Human(); } }
@Test public void test() { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); Human human = ctx.getBean("human", Human.class); System.out.println(human); }
注意:要想让bean被IoC容器管理,常见的有如下几种方式:
方式一:
@Component public class Food { // ... }
方式二:
public class Food { // ... }
<bean id="food" class="programmer.lp.domain.Food"> <!-- ...属性... --> </bean>
方式三:
public class Food { // ... }
@Configuration public class BeanConfiguration { @Bean public Food food() { return new Food(); } }
方式四:
public class Food { // ... }
public class FoodFactoryBean implements FactoryBean<Food> { @Override public Food getObject() throws Exception { // 假设Food对象创建过程很复杂 return new Food(); } @Override public Class<?> getObjectType() { return Food.class; } }
@Configuration public class BeanConfiguration { // ... @Bean public FoodFactoryBean food() { return new FoodFactoryBean(); } }
方式五:
public class Food { // ... }
@Component("food") public class FoodFactoryBean implements FactoryBean<Food> { @Override public Food getObject() throws Exception { // 假设Food对象创建过程很复杂 return new Food(); } @Override public Class<?> getObjectType() { return Food.class; } }
方式X:只要能被IoC容器管理就行。
…
核心思想:要想使用@Autowired自动注入某个对象,就必须确保这个对象存在于IoC容器中,必须被容器所管理。
例子:
这里Human没有给food属性使用@Autowired
public class Human { private Food food; public void setFood(Food food) { this.food = food; } }
实现一:
@Configuration public class BeanConfiguration { // 前提:Food必须要存在于IoC容器中,见上面几种方式 // 使用@Bean修饰的方法,Spring会使用@Autowired自动注入方法参数 @Bean public Human human(Food food) { Human human = new Human(); human.setFood(food); return human; } }
实现二:
@Configuration public class BeanConfiguration { @Bean public Food food() { return new Food(); } @Bean public Human human() { Human human = new Human(); // 这儿看起来直接调用了food()方法,但是实际上并不会直接调用 // Spring在底层使用了动态代理技术,直接调用时,会调用代理对象的代理方法 // 最终实现肯定还是ctx.getBean() human.setFood(food()); return human; } }
DogFactoryBean:
public class DogFactoryBean implements FactoryBean<Dog> { @Override public Dog getObject() throws Exception { // 假设Dog对象创建过程很复杂 return new Dog(); } @Override public Class<?> getObjectType() { return Dog.class; } }
使用方式一:
@Configuration public class BeanConfiguration { // ... @Bean public DogFactoryBean dog() { return new DogFactoryBean(); } }
使用方式二:
@Component("dog") public class DogFactoryBean implements FactoryBean<Dog> { @Override public Dog getObject() throws Exception { // 假设Dog对象创建过程很复杂 return new Dog(); } @Override public Class<?> getObjectType() { return Dog.class; } }
使用方式三:
<bean id="dog" class="programmer.lp.factorybean.DogFactoryBean"/>
测试:
@Test public void dogTest() { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println(ctx.getBean("dog")); System.out.println(ctx.getBean("&dog")); }
public class Dog { private String name; private String nickName; // ... }
@Configuration @PropertySource("dog.properties") public class BeanConfiguration { private String dogName; private String dogNickName; @Value("${name}") public void setDogName(String dogName) { this.dogName = dogName; } @Value("${nickName}") public void setDogNickName(String dogNickName) { this.dogNickName = dogNickName; } @Bean public Dog dog() { Dog dog = new Dog(); dog.setName(dogName); dog.setNickName(dogNickName); return dog; } }
@Autowired
自动注入某个对象,就必须确保这个对象存在于IoC容器中,必须被容器所管理小码哥-李明杰: Java从0到架构师③进阶互联网架构师.
本文完,感谢您的关注支持!