♥♥♥Spring 注解注入详解+Spring注入面试题♥♥♥

目录

1.注解注入示例

Q1:对象的创建是在初始化容器的时候还是在getBean方法的时候?

Q2:如果通过相同的key调用两次getBean方法,那么拿到的对象是同一个吗?

 Q3:容器中对象的生命周期


Spring注入的方式有两种,一种是通过xml文件来实现,另一种则是通过注解的方式来实现。注解方式注入比xml文件方式注入更为简单。

如上图所示,无论是哪种注入方式,都是先将类的配置信息存入map中,然后再将实例化的对象存入BeanPool中。

1.注解注入示例

实现创建一个类:SpringConfig

package org.example;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan("org.beans")
public class SpringConfig {
}

其中SpringConfig类就相当于application-context.xml文件,@ComponentScan注解指定了要扫描的包路径,即需要把哪个包下面的类(具有@ComponentScan注解的类)添加到BeanFactory中。

接下来在org.beans包下添加一个类:DefauleCache

package org.beans;

import org.springframework.stereotype.Component;

@Component
public class DefaultCache {
}

@Component注解表示此类需要加入到BeanFactory中。同时Component可以指定key,如@Component("cache"),如果不指定,key默认为类名的首字母小写所得到的字符串。

编写测试类如下:

package org.example;

import org.beans.DefaultCache;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestBase {
    protected AnnotationConfigApplicationContext ctx;
    @Before
    public void init(){
        //xml形式的配置
       /* ctx = new ClassPathXmlApplicationContext("spring-context.xml");*/
        //注解形式的配置
         ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
    }
    @Test
    public void testCtx(){
        System.out.println(ctx);
        DefaultCache cache = ctx.getBean("defaultCache", DefaultCache.class);
        System.out.println(cache);
    }
}

可以看到ctx和bean都已经拿到了。 

这样我们就省掉了编写xml文件的方法,直接用注解的方式就可以直接实现注入。

Q1:对象的创建是在初始化容器的时候还是在getBean方法的时候?

答:默认情况下,对象的创建是在容器初始化的时候,但是如果有业务需要,让类在需要使用时再进行创建,可以使用@Lazy延迟加载注解,如:

package org.beans;

import org.springframework.stereotype.Component;

@Lazy
@Component
public class DefaultCache {
}

Q2:如果通过相同的key调用两次getBean方法,那么拿到的对象是同一个吗?

默认情况下,容器中对象的作用域是"singleton",即单例,那么两次获取同一个对象得到的实例时相同的。

如下测试:

首先我们再DefaultCache类中添加构造方法去打印一些信息,如下:

package org.beans;

import org.springframework.stereotype.Component;

@Component
public class DefaultCache {
    public DefaultCache(){
        System.out.println("DefaultCache");
    }
}

测试文件如下:

package org.example;

import org.beans.DefaultCache;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestBase {
    protected AnnotationConfigApplicationContext ctx;
    @Before
    public void init(){
       /* ctx = new ClassPathXmlApplicationContext("spring-context.xml");*/
         ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
    }
    @Test
    public void testCtx(){
        /*System.out.println(ctx);*/
        DefaultCache cache1 = ctx.getBean("defaultCache", DefaultCache.class);
        DefaultCache cache2 = ctx.getBean("defaultCache", DefaultCache.class);
        System.out.println(cache1==cache2);
    }
}

 可以看到,只调用了一次构造方法,且得到的两个实例是相等的。

如果我们需要每次拿到不同的对象,可以使用@Scope注解去改变对象的作用域。

如修改DefaultCache类:

package org.beans;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

//表示getBean时都创建出一个新的实例
@Scope("prototype")
@Component
public class DefaultCache {
    public DefaultCache(){
        System.out.println("DefaultCache");
    }
}

继续执行测试方法:

可以发现DefaultCache的构造方法被执行了两次,并且两个实例是不相等的。

另外需要注意Scope为prototype的对象是不会放入Bean容器中的,只有Scope为singletor的对象才会放入池中。 

 Q3:容器中对象的生命周期

Scope为singletor的对象的生命周期为容器初始化到容器关闭,而Scope为prototype的对象Spring容器只负责创建它,但是其生命周期并不由Spring进行管理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值