新建一个 PrototypeConfig 类,内容如下:
@Configurationpublic class PrototypeConfig {
@Bean
@Scope("prototype")
public Writer getWriterPrototype() {
return new Writer();
}
}
可以使用 Spring 定义的常量来代替字符串 prototype:
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)新建 PrototypeMain 类,代码如下:
public class PrototypeMain {public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PrototypeConfig.class);
Writer writer1 = context.getBean(Writer.class);
Writer writer2 = context.getBean(Writer.class);
System.out.println(writer1);
System.out.println(writer2);
writer1.setName("沉默王二");
System.out.println(writer2.getName());
context.close();
}
}
程序输出的结果如下所示:
commonuse.Writer@78a2da20commonuse.Writer@dd3b207
null
writer1 和 writer2 两个对象的字符串表示形式完全不一样,一个是 commonuse.Writer@78a2da20,另一个是 commonuse.Writer@dd3b207;另外,虽然 writer1 对象的 name 被改变为“沉默王二”,但 writer2 的 name 仍然为 null。
从结果中我们可以得出这样的结论:Scope 为 prototype 的时候,每次调用 getBean() 都会返回一个新的实例,它们不是同一个对象。更改它们其中任意一个对象的状态,另外一个并不会同时改变。
3)request、session、application、websocket
这 4 个作用域仅在 Web 应用程序的上下文中可用,在实践中并不常用。request 用于为 HTTP 请求创建 Bean 实例,session 用于为 HTTP 会话创建 Bean 实例, application 用于为 ServletContext 创建 Bean 实例,而 websocket 用于为特定的 WebSocket 会话创建 Bean 实例。
02、Bean 的字段注入“二哥,据说 Spring 开发中经常涉及调用各种配置文件,需要用到 @Value 注解,你能给我详细说说吗?”
“没问题啊。”
1)注入普通字符串
来新建一个 ValueConfig 类,内容如下:
@Configurationpublic class ValueConfig {
@Value("沉默王二")
private String name;
public void output() {
System.out.println(name);
}
}
@Value 注解用在成员变量 name 上,表明当前注入 name 的值为“沉默王二”。
来新建一个 ValueMain 类,内容如下:
public class ValueMain {public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpELStringConfig.class);
SpELStringConfig service = context.getBean(SpELStringConfig.class);
service.output();
context.close();
}
}
程序输出结果如下:
沉默王二结果符合我们的预期。
2)注入 Spring 表达式
使用 @Value 注入普通字符串的方式最为简单,我们来升级一下,注入 Spring 表达式,先来个加法运算吧。
@Value("#{18 + 12}") // 30private int add;
双引号中需要用到 #{}。再来个关系运算和逻辑运算吧。
@Value("#{1 == 1}") // trueprivate boolean equal;
@Value("#{400 > 300 || 150 < 100}") // true
private boolean or;
觉得还不够刺激,再来个三元运算吧。
@Value("#{2 > 1 ? '沉默是金' : '不再沉默'}") // "沉默是金"private String ternary;
3)注入配置文件
假如你觉得以上这些都不够有意思,那来注入配置文件吧。
在 resources 目录下新建 value.properties 文件,内容如下:
name=沉默王二age=18