spring獲取bean的幾種方式
使用jdk:1.8、maven:3.3.3
spring獲取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>cn.ac.iie</groupId> <artifactId>spring-course</artifactId> <version>1.0-SNAPSHOT</version> <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>5.0.0.RELEASE</version> </dependency> </dependencies> </project>
配置類MyConfig.java:
package com.edu.spring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 配置類 */ @Configuration public class MyConfig { // 配置一個bean @Bean public MyBean createMyBean(){ return new MyBean(); } }
MyBean.java
package com.edu.spring;
public class 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); // 從容器中獲取bean---從型別獲取 System.out.println(context.getBean(MyBean.class)); // 從容器中獲取bean---從名字獲取,預設名字是方法名 System.out.println(context.getBean("createMyBean")); context.close(); } }
輸出結果如下:
com.edu.spring.MyBean@1445d7f
com.edu.spring.MyBean@1445d7f
如果需要指定bean名字,需要修改MyConfig.java:
@Configuration
public class MyConfig {
// 配置一個bean
@Bean(name = "myBean")
public MyBean createMyBean(){
return new MyBean();
}
}
然後在App.java指定Bean的名字:這樣就無法根據方法名獲取Bean了。
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
// 從容器中獲取bean---從型別獲取
System.out.println(context.getBean(MyBean.class));
// 從容器中獲取bean---從名字獲取,預設名字是方法名
// System.out.println(context.getBean("createMyBean"));
// 從容器中獲取bean---從指定名字獲取
System.out.println(context.getBean("myBean"));
context.close();
}
}
Bean預設是單例
我們可以看到,Bean是單例的,兩次打印出的物件是一樣的。
如果我們想修改Bean的單例為多例,修改MyConfig.java如下(新增scope(prototype)):
@Configuration
public class MyConfig {
// 配置一個bean
@Bean(name = "myBean")
@Scope("prototype")
public MyBean createMyBean(){
return new MyBean();
}
}
列印如下:
com.edu.spring.MyBean@10b48321
com.edu.spring.MyBean@6b67034
FactoryBean
新建方法JeepFactoryBean.java
package com.edu.spring;
import org.springframework.beans.factory.FactoryBean;
public class JeepFactoryBean implements FactoryBean<Jeep> {
/**
* 建立的例項物件
* @return
* @throws Exception
*/
@Override
public Jeep getObject() throws Exception {
return new Jeep();
}
/**
*
* @return
*/
@Override
public Class<?> getObjectType() {
return Jeep.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
在MyConfig.java中新增配置:
@Bean
public JeepFactoryBean createJeepFactoryBean(){
return new JeepFactoryBean();
}
可以在App.java中得到Jeep.class。
System.out.println(context.getBean(Jeep.class)); System.out.println(context.getBean("createJeepFactoryBean"));
如果要獲取JeepFactoryBean本身,而不是工廠生產出的類,可以通過下面的兩種方式獲取:
System.out.println(context.getBean(JeepFactoryBean.class)); System.out.println(context.getBean("&createJeepFactoryBean"));
目前有兩種方式進行Bean的裝配,一種是使用FactoryBean,一種是原始方式
使用第三種裝配
新建CarFactory.java
public class CarFactory {
public Car create(){
return new Car();
}
}
新建Car.java
配置MyConfig.java
@Bean
public Car createJeep(CarFactory carFactory){
return carFactory.create();
}
@Bean
public CarFactory createCarFactory(){
return new CarFactory();
}
獲取物件:
System.out.println(context.getBean(Car.class));
因為,在Bean的裝配過程中,需要引數的時候,spring會預設從當前容器中獲取到對應的引數,然後注入。
Bean初始化,在Bean初始化時,進行一些操作。
方式一:
建立Cat.java
package com.edu.spring;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class Cat implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("====afterPropertiesSet====");
}
@Override
public void destroy() throws Exception {
System.out.println("====destroy====");
}
}
配置MyConfig.java
@Bean
public Cat createCat(){
return new Cat();
}
獲得cat
System.out.println(context.getBean(Cat.class));
控制檯列印:
====afterPropertiesSet====
com.edu.spring.MyBean@7fe8ea47
com.edu.spring.MyBean@226a82c4
com.edu.spring.JeepFactoryBean@731f8236
com.edu.spring.JeepFactoryBean@731f8236
com.edu.spring.Jeep@255b53dc
com.edu.spring.Jeep@255b53dc
com.edu.spring.Car@1dd92fe2
com.edu.spring.Cat@6b53e23f
====destroy====
方法二:
建立Dog.java
package com.edu.spring;
public class Dog {
public void myInit(){
System.out.println("init=====");
}
public void myDestory(){
System.out.println("destory===");
}
}
在配置MyConfig.java時指定初始化時執行和銷燬時執行的方法
@Bean(initMethod = "myInit", destroyMethod = "myDestory")
public Dog createDog(){
return new Dog();
}
方式三:
新建Fish.java
package com.edu.spring;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class Fish {
@PostConstruct
public void initial(){
System.out.println("fish init");
}
@PreDestroy
public void close(){
System.out.println("fish close");
}
}
配置MyConfig.java
@Bean
public Fish createFish(){
return new Fish();
}
Bean裝配
新建User.java
package com.edu.spring;
import org.springframework.stereotype.Component;
@Component
public class User {
}
修改App.java,將User.class
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class, User.class);
System.out.println(context.getBean(User.class));
但是使用@Component,無法使用@Bean(initMethod = "myInit", destroyMethod = "myDestory")設定初始化和銷燬的方法
此外,預設的名字是類名。可以指定名字:
@Component("myUs