欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring boot基于Java的容器配置講解

 更新時間:2019年04月03日 14:59:53   作者:dust1  
這篇文章主要介紹了spring boot基于Java的容器配置講解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

spring容器是負責實例化、配置、組裝組件的容器。

容器的配置有很多,常用的是xml、Java注解和Java代碼。

在spring中Ioc容器相關部分是context和beans中。其中context-support保存著許多線程的容器實現。比如AnnotationConfigApplicationContext或者ClassPathXmlApplicationContext。兩者只有接收的目標不同,前者接收Java類后者接收Xml文件。但作為spring容器的不同實現殊途同歸。

下面我通過spring文檔中的介紹來自己過一遍容器配置,來加深印象。這里我使用的是springboot。所以有些基于web.xml的配置不會涉及到。

@Bean和@Configuration

@Configuration注解的類,表示這個類是一個配置類,類似于<beans></beans>或者.xml文件。

@Bean注解用來說明使用springIoc容器管理一個新對象的實例化、配置和初始化。類似于<bean></bean>,默認情況下,bean名稱就是方法名稱.

例子:

@Configuration
public class Conf {
  
  @Bean
  public HelloService helloService() {
    return new HelloServiceImpl();
  }
  
}

這種配置方式就類似于xml配置中的

<beans>
  <bean id="helloService" class="com.dust.service.impl.HelloServiceImpl" />
</beans>

等價于注解配置中的

@Service
public class HelloServiceIMpl implements HelloService {
  
  @Override
  public String hello() {
    return "hello world";
  }
  
}

使用AnnotationConfigApplicationContext實例化Spring容器

這是在spring3.0加入的功能,除了接收@Configuration注解的類作為輸入類之外還可以接受使用JSR-330元數據注解的簡單類和@Component類。

當@Configuration注解的類作為輸入時,@Configuration類本身會被注冊為一個bean,在這個類中所有用@Bean注解的方法都會被定義為一個bean。

具體有哪些類型的bean可以方法遍歷打印容器中的bean。

  public static void main(String[] args) {
    ApplicationContext context = new AnnotationConfigApplicationContext(Conf.class);
    HelloService helloService = context.getBean(HelloService.class);
    String hello = helloService.hello();
    System.out.println(hello);
  }

該實例的步驟為:

1. 創(chuàng)建AnnotationConfigApplicationContext容器對象,同時將@Configuration注解的Conf.class作為參數傳入。
2. 容器回根據傳入的Conf類來構建bean。其中就有helloService
3. 通過bean的對象類型獲取到容器中保管的對象。
4. 執(zhí)行對象方法

但是AnnotationConfigApplicationContext并不僅使用@Configuration類。任何@Component或JSR-330注解的類都可以作為輸入提供給構造函數。例如:

  public static void main(String[] args) {
    ApplicationContext context = new AnnotationConfigApplicationContext(HelloServiceImpl.class, A.class, B.class);
    HelloService helloService = context.getBean(HelloService.class);
    String hello = helloService.hello();
    System.out.println(hello);
  }

上面假設MyServiceImpl、A和B都用了Spring的依賴注入的注解,例如@Autowired。

使用register(Class<?>…)的方式構建容器

也可以使用無參構造函數實例化AnnotationConfigApplicationContext,然后使用register()方法配置。當使用編程方式構建AnnotationConfigApplicationContext時,這種方法特別有用。

例子:

  public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(Conf.class);
    context.refresh();
    HelloService helloService = context.getBean(HelloService.class);
    String hello = helloService.hello();
    System.out.println(hello);
  }

其中的refresh方法是一個初始化工作。否則注冊的類并不會被生成bean。

使用scan(String …)組件掃描

組件掃描,只需要設置好對應包路徑,spring容器回自動掃描包下面所有能夠被容器初始化的Java類。

使用注解:

@Configuration
@ComponentScan("com.example.springdemo.beans")
public class Conf {

  @Bean
  public HelloService helloService() {
    //用這種方法創(chuàng)建的service相當于用@Service注解標注
    return new HelloServiceImpl();
  }

}

在該路徑下還有一個配置文件:

@Configuration
public class Conf2 {

  @Bean
  public ByeService byeService() {
    //用這種方法創(chuàng)建的service相當于用@Service注解標注
    return new ByeServiceImpl();
  }

}

然后是初始化容器:

  public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(Conf.class);
    context.refresh();
    ByeService byeService = context.getBean(ByeService.class);
    String hello = byeService.bye();
    System.out.println(hello);
  }

可以看到,雖然傳入的是Conf類,但是由于包掃描機制,該容器同時創(chuàng)建了Conf2類中的bean。

這就類似xml配置中的:

<beans>
  <context:component-scan base-package="com.example.springdemo.beans"/>
</beans>

還可以直接調用容器的掃描方法

  public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//    context.register(Conf.class);
    context.scan("com.example.springdemo.beans");
    context.refresh();
    ByeService byeService = context.getBean(ByeService.class);
    String hello = byeService.bye();
    System.out.println(hello);
  }

springboot中的包掃描

springboot通過main方法啟動,其中的注解為@SpringBootApplication。通過查看該注解的代碼可以發(fā)現一下代碼段:

@AliasFor(
  annotation = ComponentScan.class,
  attribute = "basePackages"
)

由此可以知道@SpringBootApplication注解包括了包掃描注解,同時掃描的是該類的目錄以及子目錄的所有可以被spring容器初始化的類

AnnotationConfigWebApplicationContext對于web應用的支持

AnnotationConfigApplicationContext在WebApplicationContext中的變體為 AnnotationConfigWebApplicationContext。當配置Spring ContextLoaderListener servlet 監(jiān)聽器、Spring MVC DispatcherServlet的時候,可以用此實現。

Bean依賴

@Bean注解方法可以具有描述構建該bean所需依賴關系的任意數量的參數。依賴的必須也是Ioc容器中注冊的bean。

將上面的代碼修改后如下:

@Configuration
public class Conf {

  @Bean
  public HelloService helloService(ByeService byeService) {
    return new HelloServiceImpl(byeService);
  }

  @Bean
  public ByeService byeService() {
    return new ByeServiceImpl();
  }

}
public class HelloServiceImpl implements HelloService {

  private ByeService byeService;

  public HelloServiceImpl(ByeService byeService) {
    this.byeService = byeService;
  }
  
  @Override
  public String hello() {
    return "hello world" + byeService.bye();
  }
  
}
  public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(Conf.class);
    context.refresh();
    HelloService helloService = context.getBean(HelloService.class);
    String hello = helloService.hello();
    System.out.println(hello);
    ByeService byeService = context.getBean(ByeService.class);
    String bye = byeService.bye();
    System.out.println(bye);
  }

輸出結果:

hello worldGoodbye!

Goodbye!

這種解決原理和基于構造函數的依賴注入幾乎相同。

生命周期回調

@Bean注解支持任意的初始化和銷毀回調方法,這與Spring XML 中bean元素上的init方法和destroy-method屬性非常相似:

  @Bean(initMethod = "init")
  public HelloService helloService(ByeService byeService) {
    return new HelloServiceImpl(byeService);
  }

  @Bean(destroyMethod = "destroy")
  public ByeService byeService() {
    return new ByeServiceImpl();
  }

public interface ByeService {

  String bye();

  void destroy();

}

public interface HelloService {

  String hello();

  void init();
}

  public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(Conf.class);
    context.refresh();
    context.close();
  }

輸出如下:

init helloService!!

destroy byeService!

默認情況下,Ioc容器關閉后所有bean都會被銷毀,但是如果要引入一個生命周期在應用程序之外進行管理的組件,例如:DataSource。那么只需要將@Bean(destroyMethod =””)添加到你的bean定義中即可禁用默認(推測)模式。

@Bean(destroyMethod="")
public DataSource dataSource() throws NamingException {
  return (DataSource) jndiTemplate.lookup("MyDS");
}

當然,初始化的時候也可以先執(zhí)行對應方法,而不用交給Ioc容器

  @Bean
  public HelloService helloService(ByeService byeService) {
    HelloService helloService = new HelloServiceImpl(byeService);
    helloService.init();
    return helloService;
  }

@Scope和scope 代理

Scope描述的是Spring容器如何新建Bean實例的。

  1. Singleton:一個Spring容器中只有一個Bean的實例,此為Spring的默認配置,全容器共享一個實例。
  2. Prototype:每次調用新建一個Bean實例。
  3. Request:Web項目中,給每一個 http request 新建一個Bean實例。
  4. Session:Web項目中,給每一個 http session 新建一個Bean實例。
  5. GlobalSession:這個只在portal應用中有用,給每一個 global http session 新建一個Bean實例。
  @Bean
  //每次調用就創(chuàng)建一個新的bean
  @Scope("prototype")
  public UserInfo userInfo() {
    return new UserInfo();
  }

  @Bean
  public UserService userService() {
    UserService userService = new UserServiceImpl();
    userService.init(userInfo());
    return userService;
  }

測試代碼:

  public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(Conf.class);
    context.refresh();
    UserService userService = context.getBean(UserService.class);
    UserService userService2 = context.getBean(UserService.class);
    UserInfo userInfo = context.getBean(UserInfo.class);
    UserInfo userInfo2 = context.getBean(UserInfo.class);
    System.out.println(userService == userService2);
    System.out.println(userInfo == userInfo2);
  }

輸出:

true

false

自定義Bean命名

通常,bean的名稱是bean的方法名,但是可以通過name屬性重命名。有時一個單一的bean需要給出多個名稱,稱為bean別名。為了實現這個目標,@Bean注解的name屬性接受一個String數組。

  @Bean(name = {"user", "userService", "User"})
  public UserService userService() {
    UserService userService = new UserServiceImpl();
    userService.init(userInfo());
    return userService;
  }
  public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(Conf.class);
    context.refresh();
    Object user = context.getBean("user");
    Object userService = context.getBean("userService");
    Object User = context.getBean("User");

    System.out.println(user == userService);
    System.out.println(user == User);
    System.out.println(userService == User);
  }

輸出:

true

true

true

Bean描述

有時候需要提供一個詳細的bean描述文本是非常有用的。當對bean暴露(可能通過JMX)進行監(jiān)控使,特別有用??梢允褂聾Description注解對Bean添加描述:

  @Bean(name = {"user", "userService", "User"})
  @Description("這是用戶服務對象")
  public UserService userService() {
    UserService userService = new UserServiceImpl();
    userService.init(userInfo());
    return userService;
  }
  public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(Conf.class);
    context.refresh();
    String description = context.getBeanDefinition("user").getDescription();
    System.out.println(description);
  }

輸出:

這是用戶服務對象

基于Java組合配置

使用@Import注解

和Spring XML文件中使用元素來幫助模塊化配置類似,@Import注解允許從另一個配置類加載@Bean定義:

@Configuration
@Import(UserConf.class)
public class Conf {

  @Bean(initMethod = "init")
  public HelloService helloService(ByeService byeService) {
    //用這種方法創(chuàng)建的service相當于用@Service注解標注
    return new HelloServiceImpl(byeService);
  }

  @Bean(destroyMethod = "destroy")
  public ByeService byeService() {
    return new ByeServiceImpl();
  }

}

@Configuration
public class UserConf {

  @Bean
  //每次調用就創(chuàng)建一個新的bean
  @Scope("prototype")
  public UserInfo userInfo() {
    return new UserInfo();
  }

  @Bean(name = {"user", "userService", "User"})
  @Description("這是用戶服務對象")
  public UserService userService() {
    UserService userService = new UserServiceImpl();
    userService.init(userInfo());
    return userService;
  }

}

  public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(Conf.class);
    context.refresh();
    String description = context.getBeanDefinition("user").getDescription();
    System.out.println(description);
  }

這種方法簡化了容器實例化,因為只需要處理一個類,而不是需要開發(fā)人員在構建期間記住大量的@Configuration注解類。

Java and XML 混合配置

Java配置并不能100%替代xml配置,因此Ioc容器支持兩者混合配置。不過這里有個區(qū)別就是以xml為中心還是以Java配置為中心。

以XML為中心

@Configuration
public class DataSourceConf {

  @Autowired
  private DataSource dataSource;

  @Bean
  public DataSourceService dataSource() {
    return new DataSourceerviceImpl(dataSource);
  }

}
jdbc.url=jdbc:mysql://39.108.119.174:3306/dust
jdbc.username=root
jdbc.password=123456

<beans>

  <context:annotation-config/>

  <context:property-placeholder location="classpath:jdbc.properties"/>

  <bean class="com.example.springdemo.beans.DataSourceConf"/>

  <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
  </bean>

</beans>

  public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/datasource.xml");
    DataSourceService dataSourceService = context.getBean(DataSourceService.class);
    System.out.println(dataSourceService.toString());
  }

以Java類為中心

<beans>
  <context:property-placeholder location="classpath:jdbc.properties"/>
</beans>
@Configuration
@ImportResource("classpath:spring/datasource.xml")
public class DataSourceConf {

  @Value("${jdbc.url}")
  private String url;

  @Value("${jdbc.username}")
  private String username;

  @Value("${jdbc.password}")
  private String password;

  @Bean
  public DataSourceService dataSource() {
    return new DataSourceerviceImpl(url, username, password);
  }

}
  public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.scan("com.example.springdemo.beans");
    context.refresh();
    DataSourceService dataSourceService = context.getBean(DataSourceService.class);
    System.out.println(dataSourceService.toString());

//    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/datasource.xml");
//    DataSourceService dataSourceService = context.getBean(DataSourceService.class);
//    System.out.println(dataSourceService.toString());
  }

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • SpringBoot?Webflux創(chuàng)建TCP/UDP?server并使用handler解析數據

    SpringBoot?Webflux創(chuàng)建TCP/UDP?server并使用handler解析數據

    這篇文章主要介紹了SpringBoot?Webflux創(chuàng)建TCP/UDP?server并使用handler解析數據,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java?GenericObjectPool?對象池化技術之SpringBoot?sftp?連接池工具類詳解

    Java?GenericObjectPool?對象池化技術之SpringBoot?sftp?連接池工具類詳解

    這篇文章主要介紹了Java?GenericObjectPool?對象池化技術之SpringBoot?sftp?連接池工具類詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • IDEA啟動Tomcat報Unrecognized option: --add-opens=java.base/java.lang=ALL-UNNAMED的解決方法

    IDEA啟動Tomcat報Unrecognized option: --add-opens=java

    這篇文章主要為大家介紹了解決IDEA啟動Tomcat報Unrecognized option: --add-opens=java.base/java.lang=ALL-UNNAMED的方法,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-08-08
  • SpringMVC MethodArgumentResolver的作用與實現

    SpringMVC MethodArgumentResolver的作用與實現

    這篇文章主要介紹了SpringMVC MethodArgumentResolver的作用與實現,MethodArgumentResolver采用一種策略模式,在Handler的方法被調用前,Spring MVC會自動將HTTP請求中的參數轉換成方法參數
    2023-04-04
  • IntellJ idea使用FileWatch實時編譯less文件的方法

    IntellJ idea使用FileWatch實時編譯less文件的方法

    這篇文章主要介紹了IntellJ idea使用FileWatch實時編譯less文件的相關資料,需要的朋友可以參考下
    2018-02-02
  • ibatis結合oracle批量插入三種方法的測評

    ibatis結合oracle批量插入三種方法的測評

    今天小編就為大家分享一篇關于ibatis結合oracle批量插入三種方法的測評,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Spring底層原理由淺入深探究

    Spring底層原理由淺入深探究

    Spring事務有可能會提交,回滾、掛起、恢復,所以Spring事務提供了一種機制,可以讓程序員來監(jiān)聽當前Spring事務所處于的狀態(tài),這篇文章主要介紹了Spring底層事務原理,需要的朋友可以參考下
    2023-02-02
  • springboot整合RabbitMQ 中的 TTL實例代碼

    springboot整合RabbitMQ 中的 TTL實例代碼

    TTL 是 RabbitMQ 中一個消息或者隊列的屬性,表明一條消息或者該隊列中的所有消息的最大存活時間,單位是毫秒,這篇文章主要介紹了springboot整合RabbitMQ 中的 TTL,需要的朋友可以參考下
    2022-09-09
  • JAXB命名空間及前綴_動力節(jié)點Java學院整理

    JAXB命名空間及前綴_動力節(jié)點Java學院整理

    這篇文章主要給大家介紹了關于JAXB命名空間及前綴的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-08-08
  • Java?Spring的核心與設計思想你知道嗎

    Java?Spring的核心與設計思想你知道嗎

    這篇文章主要為大家詳細介紹了Java?Spring的核心與設計思想,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03

最新評論