spring注解开发-自动装配

自动装配:Spring利用依赖注入,完成对IOC容器中的各个组件的依赖关系赋值


1.@Autowired

1)、默认优先按照类型去容器中找对应的组件---->ioc.getBean(BookDao.class);,如果找到了就赋值

2)、如果找到了多个相同类型的组件,再讲属性的名称作为组件的id去查找--->ioc.getBean("bookDao");

3)、使用@Qualifier("bookDao")来明确指定需要装配的组件的id,而不是使用属性名作为id

4)、自动装配默认的是一定要在容器中找到组件,如果容器中没有就会报错

                 可以设置required = false,是其不必须在容器中找到组件,找不到就是null

@Autowired(required = false)

5)、容器中有多个相同类型的组件,还可以使用@Primary设置每次装配首选的是这个bean,和@Qualifier一起使用 ,还是会自动装配@Qualifier明确指定的bean

给BookService自动注入BookDao 

@Service
public class BookService {
    @Qualifier("bookDao")
    @Autowired
    private BookDao bookDao;

    public BookDao getBookDao() {
        return bookDao;
    }

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    @Override
    public String toString() {
        return "BookService{" +
                "bookDao=" + bookDao +
                '}';
    }
}

测试结果:

BookService里的BookDao自动装配成功


2.Spring还支持@Resource(JSR250)和@Inject(JSR330),java规范的注解

1.@Resource:可以和@Autowired一样实现自动装配功能,没有@Primary,也没有required属性

2.@Inject:使用需要导入javax.inject包,和@Autowired一样实现自动装配功能,支持@Primary,没有required属性


3.@Autowired的其他用法

@Autowired:不仅可以也在属性上,还能标注在方法上、构造器上、参数上

①、标注在方法上测试

@Bean+方法参数:参数从容器中获取(@Autowired 可以省略)

    @Bean
    public Boss boss(@Autowired Car car){
        return new Boss();
    }

在setCar方法上标注@Autowired:

@Component
public class Boss {

    private Car car;

    public Car getCar() {
        return car;
    }

    /*
    * 将Autowired标注在方法上
    * Spring容器创建对象就会调用这个方法完成赋值
    * 方法使用的自定义的值从ioc容器中获取
    * */
    @Autowired
    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Boss{" +
                "car=" + car +
                '}';
    }
}

测试结果:


②、构造器

默认加在容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值

如果组件只有一个有参构造器,那么有参构造器的Autowired可以省略


@Autowired标注在Boss的有参构造器上:

@Component
public class Boss {

    private Car car;


    //构造器要用的组件都是从ioc容器中获取
    @Autowired
    public Boss(Car car) {
        this.car = car;
        System.out.println("Boss的有参构造器。。。。");
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Boss{" +
                "car=" + car +
                '}';
    }
}

测试结果: 

③、参数上

标注在参数上效果一样,不多测试


4.自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,.....)

自定义组件实现xxxAware接口:在创建对象的时候,会调用接口规定的方法注入相关组件


例子:实现了ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware三个Aware接口

@Component
public class Red implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {
    private ApplicationContext applicationContext;

    //获取ioc容器
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        System.out.println("传入的IOC: "+applicationContext);
    }

    //获取bean名字
    public void setBeanName(String name) {
        System.out.println("当前Bean的名字: "+name);
    }

    //
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        String s = resolver.resolveStringValue("你好${os.name} 我是#{2*4}");
        System.out.println("解析的字符串:"+s);
    }
}

在容器创建Red对象时调用Aware的方法

结果:


Aware的原理

Debug运行:

查看方法调用栈的信息:

先调用了postProcessBeforeInitialization(final Object bean, String beanName)方法,

在方法里调用了

invokeAwareInterfaces方法:

	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof EnvironmentAware) {
				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
			}
			if (bean instanceof EmbeddedValueResolverAware) {
				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
			}
			if (bean instanceof ResourceLoaderAware) {
				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
			}
			if (bean instanceof ApplicationEventPublisherAware) {
				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
			}
			if (bean instanceof MessageSourceAware) {
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}
			if (bean instanceof ApplicationContextAware) {
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}

判断当前的bean是否实现了这些接口,如果实现了就调用该接口的方法 ,传入组件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值