(001)spring容器创建bean的两种方式
Posted 明月之诗
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(001)spring容器创建bean的两种方式相关的知识,希望对你有一定的参考价值。
简单记录一下spring容器创建、装配、管理bean
1、使用@Configuration、@Bean的注解组合创建bean
可以用两种方法获取bean,根据类名或者创建bean的方法名,如果不指定bean的名字,默认bean的名字是该方法名。
pom.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.edu.spring</groupId> <artifactId>spring</artifactId> <version>1.0.0</version> <name>spring</name> <!-- FIXME change it to the project\'s website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.2.RELEASE</version> </dependency> </dependencies> </project>
MyBean.java如下:
package com.edu.spring; public class MyBean { }
MyConfig.java如下:
package com.edu.spring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean public MyBean createMyBean() { return new MyBean(); } }
App.java如下:
package com.edu.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App { public static void main( String[] args ) { AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class); System.out.println(context.getBean(MyBean.class)); System.out.println(context.getBean("createMyBean")); context.close(); } }
运行结果如下:
指定bean的名字,可以在@bean添加name属性,如下:
package com.edu.spring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean(name="myBean") public MyBean createMyBean() { return new MyBean(); } }
同样获取bean时,将App.java中修改为bean的name中指定的,如下:
package com.edu.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App { public static void main( String[] args ) { AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class); System.out.println(context.getBean(MyBean.class)); System.out.println(context.getBean("myBean")); context.close(); } }
运行结果如下:
上面两个运行结果可以发现,bean是单例的,使用@Scope("prototype")将单例修改为多例:
package com.edu.spring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @Configuration public class MyConfig { @Bean(name="myBean") @Scope("prototype") public MyBean createMyBean() { return new MyBean(); } }
运行结果如下:
使用@Configuration、@Bean的注解组合的变体创建bean
Car.java
package com.edu.spring; public class Car { }
CarFactory.java
package com.edu.spring; public class CarFactory { public Car create(){ return new Car(); } }
MyConfig.java spring容器装配CarFactory这个bean,创建Car这个bean的时候,形参接收的是spring容器已经创建的CarFactory这个bean
package com.edu.spring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean public CarFactory createJeepFactory(){ return new CarFactory(); } @Bean public Car createCar(CarFactory factory){ return factory.create(); } }
App.java
package com.edu.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App { public static void main( String[] args ) { AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class); System.out.println(context.getBean(Car.class)); context.close(); } }
运行结果如下:
2、实现FactoryBean接口创建bean
FactoryBean有3个方法,获取对象、获取对象类型、默认不是单例,如下:
RunnableFactoryBean.java实现FactoryBean接口如下:
package com.edu.spring; import org.springframework.beans.factory.FactoryBean; public class RunnableFactoryBean implements FactoryBean<Runnable> { @Override public Runnable getObject() throws Exception { // TODO Auto-generated method stub return () -> {}; } @Override public Class<?> getObjectType() { // TODO Auto-generated method stub return Runnable.class; } @Override public boolean isSingleton() { // TODO Auto-generated method stub return true; } }
配置类MyConfig.java中给RunnableFactoryBean添加Bean注解如下:
package com.edu.spring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean public RunnableFactoryBean createRunnableFactoryBean(){ return new RunnableFactoryBean(); } }
App.java如下:
package com.edu.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App { public static void main( String[] args ) { AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class); System.out.println(context.getBean(RunnableFactoryBean.class)); System.out.println(context.getBean(Runnable.class)); context.close(); } }
运行结果如下:
可以看到RunnableFactoryBean与Runnable的Bean都可以获取,Runnable是用Lambda实现的,所以看起来有点怪,下面不用Lambda表达式
Jeep.java
package com.edu.spring; public class Jeep { }
RunnableFactoryBean.java
package com.edu.spring; import org.springframework.beans.factory.FactoryBean; public class RunnableFactoryBean implements FactoryBean<Jeep> { @Override public Jeep getObject() throws Exception { // TODO Auto-generated method stub return new Jeep(); } @Override public Class<?> getObjectType() { // TODO Auto-generated method stub return Jeep.class; } @Override public boolean isSingleton() { // TODO Auto-generated method stub return true; } }
MyConfig.java
package com.edu.spring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean public RunnableFactoryBean createRunnableFactoryBean(){ return new RunnableFactoryBean(); } }
App.java 根据类获取与根据bean的名字获取是一样的
package com.edu.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App { public static void main( String[] args ) { AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class); System.out.println(context.getBean(RunnableFactoryBean.class)); System.out.println(context.getBean(Jeep.class)); System.out.println(context.getBean("createRunnableFactoryBean")); context.close(); } }
运行结果如下:
将RunnableFactoryBean.java中改为不是单例
package com.edu.spring; import org.springframework.beans.factory.FactoryBean; public class RunnableFactoryBean implements FactoryBean<Jeep> { @Override public Jeep getObject() throws Exception { // TODO Auto-generated method stub return new Jeep(); } @Override public Class<?> getObjectType() { // TODO Auto-generated method stub return Jeep.class; } @Override public boolean isSingleton() { // TODO Auto-generated method stub return false; } }
App.java 两次获取的bean不一样
package com.edu.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App { public static void main( String[] args ) { AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class); System.out.println(context.getBean(RunnableFactoryBean.class)); System.out.println(context.getBean(Jeep.class)); System.out.println(context.getBean("createRunnableFactoryBean")); context.close(); } }
运行结果如下:
从MyConfig.java中可以看到,创建的bean是RunnableFactoryBean,根据名字获取:context.getBean("createRunnableFactoryBean"))得到的却是泛型中的类的bean:com.edu.spring.Jeep@6e2c9341,这是因为RunnableFactoryBean实现了FactoryBean接口,这个接口是特殊的,如果要根据RunnableFactoryBean的名字获取bean,可以用下面方式:
App.java 中名字前面加&
package com.edu.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App { public static void main( String[] args ) { AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class); System.out.println(context.getBean(Jeep.class)); System.out.println(context.getBean("createRunnableFactoryBean")); System.out.println(context.getBean(RunnableFactoryBean.class)); System.out.println(context.getBean("&createRunnableFactoryBean")); context.close(); } }
运行结果如下:
以上是关于(001)spring容器创建bean的两种方式的主要内容,如果未能解决你的问题,请参考以下文章
Spring(十三):使用工厂方法来配置Bean的两种方式(静态工厂方法&实例工厂方法)
Spring 注入 Bean 的 7 种方式,还有谁不会?-