04 Spring 注解配置,簡化xml配置,@Service、@Autowired簡介

轉(zhuǎn)載請注明來源 賴賴的博客

導語

簡單的不一定是好的,復雜的也不一定是好的,合適的才是最好的。

通過增加Spring注解從而簡化Xml配置,并提供實例。

建議先了解Spring ApplicationContext的xml配置方式??蓞⒖?strong>03 Spring IoC之對象間的相互關(guān)系和 Spring 應用結(jié)構(gòu)

實例

如果看過 03 Spring IoC之對象間的相互關(guān)系和 Spring 應用結(jié)構(gòu) 可以跳到項目詳解這一節(jié),因為結(jié)構(gòu)和輸出結(jié)構(gòu)與上一節(jié)一致。

項目工程目錄結(jié)構(gòu)和代碼獲取地址

獲取地址(版本Log將會注明每一個版本對應的課程)

https://github.com/laiyijie/SpringLearning

目錄結(jié)構(gòu)

目錄結(jié)構(gòu)

運行工程

運行具有Main函數(shù)的 App.java
得到如下輸出

false

工程簡單分層(如果看過 03 Spring IoC之對象間的相互關(guān)系和 Spring 應用結(jié)構(gòu) 可以略過到下一節(jié))

現(xiàn)在工程有三個包,包之間的關(guān)系如下:

  • 應用層:me.laiyijie.demo , 只調(diào)用服務層
  • 服務層:me.laiyijie.demo.service,只調(diào)用數(shù)據(jù)層
  • 數(shù)據(jù)層:me.laiyijie.demo.dataaccess,最底層,直接操作持久化數(shù)據(jù)(文件、數(shù)據(jù)庫等)

項目詳解

從App.java入手

App.java(與上一節(jié)比無變化)

package me.laiyijie.demo;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import me.laiyijie.demo.service.UserService;

public class App {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("root-context.xml");
        
        UserService userService = context.getBean(UserService.class);
        
        System.out.println(userService.login("lailai", "laiyijie","127.0.0.1"));
        
        context.close();
    }
}

Main函數(shù)中依舊只有四行代碼,這里引用到了UserService,并且調(diào)用了UserServicelogin方法。

我們來看下UserService

UserService.java(與上一節(jié)比無變化)

package me.laiyijie.demo.service;

public interface UserService{
    
    boolean login(String username,String password,String ip);
    
}

OK,非常簡單,只是一個接口,定義了有這么一個方法,具體實現(xiàn)是在同一個包下面的另一個文件,UserServiceImpl.java中

UserServiceImpl.java(變化來了?。?/h4>
package me.laiyijie.demo.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import me.laiyijie.demo.dataaccess.AccountAccess;
import me.laiyijie.demo.dataaccess.LoginLogAccess;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private AccountAccess accountAccess;
    @Autowired
    private LoginLogAccess loginLogAccess;
    
    public boolean login(String username, String password,String ip) {
        
        if (!accountAccess.isAccountExist(username)) {
            return false;
        }
        
        if (accountAccess.isPasswordRight(username, password)) {
            accountAccess.updateLastLoginTime(username);
            loginLogAccess.addLoginLog(username, ip);
            return true;
        }
        return false;
    }
}

在這里新增了兩個注解 @Service、@Autowired ,減少了getter和setter

  • @Service 在類前注釋,將此類實例化,等同于在root-context中配置

      <bean class="me.laiyijie.demo.service.UserServiceImpl">
      </bean>
    
  • @Autowired 在屬性前配置,將屬性對應的對象從工廠中取出并注入到該bean中,等同于

      <property ref="accountAccessImpl" name="accountAccess"></property>
      <property ref="loginLogAccessImpl" name="loginLogAccess"></property>
    

兩個注解組合起來等同于:

<bean class="me.laiyijie.demo.service.UserServiceImpl">
    <property ref="accountAccessImpl" name="accountAccess"></property>
    <property ref="loginLogAccessImpl" name="loginLogAccess"></property>
</bean>

那么,讓我們看一下root-context.xml是否可以去除掉這一部分的配置!

root-context.xml(有變化)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

    <bean id="accountAccessImpl" class="me.laiyijie.demo.dataaccess.AccountAccessImpl"></bean>
    <bean id="loginLogAccessImpl" class="me.laiyijie.demo.dataaccess.LoginLogAccessImpl"></bean>
    
    <context:component-scan base-package="me.laiyijie.demo.service"></context:component-scan>

</beans>

yes!你沒看錯,配置me.laiyijie.demo.service.UserServiceImpl這個bean的代碼被兩個注解代替了,而新增了一行:

<context:component-scan base-package="me.laiyijie.demo.service"></context:component-scan>

從文字直譯就可以看出,這一行代表了

  • me.laiyijie.demo.service包下面掃描 componet

而@Service正是componet 中的一種

進一步簡化

是否可以更進一步簡化root-context.xml的配置?!因為還有兩個bean是用xml配置的??!

當然可以,通過如下步驟

  1. 刪除root-context.xml中的兩行bean配置

  2. 在AccountAccessImpl.java和LoginLogAccess.java的類定義前增加@Service注解

  3. 修改root-context.xml 中componet-scan的 base-package屬性為me.laiyijie.demo,如下所示

     <context:component-scan base-package="me.laiyijie.demo"></context:component-scan>
    

小結(jié):

  1. @Service可以將一個類定義成一個bean(也就是實例化并放入工廠)
  2. @Autowired 可以根據(jù)屬性的類型來注入工廠中存在的該類型的實例
  3. 要使用注解,需要在ApplicationContext中增加 <context:component-scan base-package="me.laiyijie.demo"></context:component-scan>配置
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,255評論 6 342
  • 來源:關(guān)于Spring IOC (DI-依賴注入)你需要知道的一切作者:zejian Dao層(AccountDa...
    楊井閱讀 5,438評論 0 27
  • 上一篇:Spring學習筆記(四、Bean裝配(上)) 這篇講解Bean管理的注解實現(xiàn)及例子 主要內(nèi)容有: Cla...
    魯克巴克詩閱讀 1,334評論 2 6
  • 為什么要搭建deb源 公司網(wǎng)絡隔離, 有一部分服務器不允許鏈接外網(wǎng) 自己開發(fā)的安裝程序需要統(tǒng)一管理 搭建步驟 在一...
    imsilence閱讀 3,117評論 0 0

友情鏈接更多精彩內(nèi)容