前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Framework 源码学习笔记(六)

Spring Framework 源码学习笔记(六)

作者头像
RiemannHypothesis
发布2022-08-19 16:01:19
1800
发布2022-08-19 16:01:19
举报
文章被收录于专栏:Elixir

Chapter 06 - @Autowire 及 Aware

Section 01 - @Autowire的位置

@Autowire出了可以放在属性上,还可以放置的setter方法上以及有参构造方法上,都可以实现Bean的自动装配

@Autowire在Setter方法上 首先给两个实体类增加@Component注解,给User增加一个Address的属性

代码语言:javascript
复制
@Component
public class User {

    private String username;
    private String password;

    private Address address;

    public User() {
        System.out.println("User 无参数构造方法被调用");
    }

    public Address getAddress() {
        return address;
    }

    @Autowired
    public void setAddress(Address address) {
        this.address = address;
    }


    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + ''' +
                ", password='" + password + ''' +
                ", address=" + address +
                '}';
    }
}
代码语言:javascript
复制
@Component
public class Address {

    private Integer id;
    private String addressDetail;

    public Address() {
        System.out.println("Address空参构造方法被调用");
    }

    public Address(Integer id, String addressDetail) {
        System.out.println("Address有参数构造方法被调用");
        this.id = id;
        this.addressDetail = addressDetail;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getAddressDetail() {
        return addressDetail;
    }

    public void setAddressDetail(String addressDetail) {
        this.addressDetail = addressDetail;
    }

    @PostConstruct
    public void init(){
        System.out.println("Address Bean 的初始化方法");
    }

    @PreDestroy
    public void destroy(){
        System.out.println("Address Bean的销毁方法");
    }
}

在BeanAutoAssembleConfig配置扫描entity包,将User和Address注册到容器中

代码语言:javascript
复制
@ComponentScan(basePackages = {"com.citi.dao","com.citi.service","com.citi.controller","com.citi.entity"})
public class BeanAutoAssembleConfig {

    //@Primary
    @Bean("personDao2")
    public PersonDao personDao(){
        return new PersonDao();
    }
}

修改BeanAutoAssembleConfigTest,执行测试

代码语言:javascript
复制
public class BeanAutoAssembleConfitTest {

    @Test
    public void isSameBean(){
        ApplicationContext context = new AnnotationConfigApplicationContext(BeanAutoAssembleConfig.class);
        System.out.println("IoC容器初始化完成");

        Address address = context.getBean("address",Address.class);
        System.out.println(address);

        User user = context.getBean("user", User.class);
        System.out.println(user.getAddress());

        // 关闭容器
        ((AnnotationConfigApplicationContext)context).close();
    }
}

执行测试,控制台打印,Address可以成功注入到User中

image.png
image.png

@Autowire在有参数的构造方法上 新增加一个只包含Address参数的User构造方法,在方法上面增加@Autowire注解,同时将Setter方法的@Autowire注解注释

代码语言:javascript
复制
@Component
public class User {

    private String username;
    private String password;

    private Address address;

    public User() {
        System.out.println("User 无参数构造方法被调用");
    }

    @Autowired
    public User(Address address) {
        System.out.println("User有参数构造方法被调用");
        this.address = address;
    }

    public Address getAddress() {
        return address;
    }

    //@Autowired
    public void setAddress(Address address) {
        this.address = address;
    }


    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + ''' +
                ", password='" + password + ''' +
                ", address=" + address +
                '}';
    }
}

其他地方不用修改,执行测试类,控制台打印如下,可以成功装配Bean,并且是通过调用User的Setter方法实现的

image.png
image.png

参考@Autowire源码,@Autowire注解可以放在构造方法,setter方法,属性及方法的参数上

image.png
image.png

Section 02 - Spring的Aware接口

修改entity包中的Product实体类,实现ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware接口,并实现接口中的方法

代码语言:javascript
复制
@Component
public class Product implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {

    private Integer id;

    private String name;

    private Integer price;

    private ApplicationContext applicationContext;

    @Override
    public void setBeanName(String name) {
        System.out.println("beanName为:" + name);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("IoC容器为:" + applicationContext);
    }

    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        String result = resolver.resolveStringValue("操作系统为:${os.name}");
        System.out.println(result);
    }
    
    // 省略getter/setter/toString方法
}

在config包中增加一个配置类BeanAwareConfig,使用@ComponentScan将entity包中的类注册到容器中

代码语言:javascript
复制
@Configuration
@ComponentScan(value = {"com.citi.entity"})
public class BeanAwareConfig {
}

在test包中增加一个测试类

代码语言:javascript
复制
public class BeanAwareConfigTest {

    @Test
    public void testAware(){

        ApplicationContext context = new AnnotationConfigApplicationContext(BeanAutoAssembleConfig.class);
        System.out.println("IoC容器初始化完成");

        Product product = context.getBean("product", Product.class);
        System.out.println(product);

        // 关闭容器
        ((AnnotationConfigApplicationContext)context).close();
    }
}

执行测试,控制台输出如下

image.png
image.png

控制台输出了IoC容器,beanName等信息,这些都是Spring 底层组件提供的 ,也就是说如果想要把Spring底层的组件注入到自定义的Bean中,需要实现相应的Aware接口,如ApplicationContextAware可以提供IoC容器,这些Aware类都是相关的Processor的后置处理器来处理。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Chapter 06 - @Autowire 及 Aware
    • Section 01 - @Autowire的位置
      • Section 02 - Spring的Aware接口
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档