Spring注解開發詳解

image.png

前言

《Spring快速入門詳解》中主要介紹了通過xml配置文件的方式進行開發,其實還可以通過注解方式進行開發。
Spring3.0升級了純注解開發模式,使用Java類替代配置文件,開啟了Spring快速開發賽道。本文主要詳細講解Spring注解方式開發。

注解開發

1. 快速入門

1.1 注解開發定義bean

1.1.1 使用@Component定義bean

@Component("bookDao")
public class BookDaoImpl implements BookDao {
}
@Component
public class BookServiceImpl implements BookService {
}

注意:如果沒有定義名稱,那么只能通過類型獲取。

1.1.2 核心配置文件中通過組件掃描加載bean

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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.xsd">

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

掃描base-package包下的所有添加@Component注解的類

1.1.3 Spring提供@Component注解的三個衍生注解

@Controller:用于表現層bean定義
@Service:用于業務層bean定義
@Repository:用于數據層bean定義

@Repository("bookDao")
public class BookDaoImpl implements BookDao {
}
@Service
public class BookServiceImpl implements BookService {
}

1.2 純注解開發

Spring3.0升級了純注解開發模式,使用Java類替代配置文件,開啟了Spring快速開發賽道。本文主要詳細講解Spring注解方式開發。

1.2.1 Java類代替Spring核心配置文件

xml配置文件被Java類代替,創建Java類如下:

@Configuration
@ComponentScan({"com.hao.service", "com.hao.dao"})
public class SpringConfig {
} 

@Configuration注解用于設定當前類為配置類。
@ComponentScan注解用于設定掃描路徑,此注解只能添加一次,多個數據請用數組格式。

1.2.2 讀取Spring核心配置文件初始化容器對象切換為讀取Java配置類初始化容器對象

// 加載配置文件初始化容器
ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
// 加載配置類初始化容器
ApplicationContext cxt = new AnnotationConfigApplicationContext(SpringConfig.class);

2. bean管理

2.1 bean作用范圍

2.1.1 使用@Scope定義bean作用范圍

@Repository
@Scope("singleton")
public class BookDaoImpl implements BookDao {
}

@Scope默認是單例singleton,可以不寫,如果需要非單例模式,修改為prototype即可。

2.2 bean生命周期

2.2.1 使用@PostConstruct、@PreDestroy定義bean生命周期

@Repository
public class BookDaoImpl implements BookDao {

    public BookDaoImpl() {
        System.out.println("book dao constructor...");
    }
    @PostConstruct
    public void init() {
        System.out.println("book dao init...");
    }
    @PreDestroy
    public void destroy() {
        System.out.println("book dao destroy...");
    }
}

自定義init()destroy()方法添加相應注解即可。

3. 依賴注入

3.1 自動裝配

3.1.1 使用@Autowired注解開啟自動裝配模式(按類型)

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
    @Override
    public void save() {
        System.out.println("book service save...");
        bookDao.save();
    }
}

注意:自動裝配基于反射設計創建對象并暴力反射對應屬性為私有屬性初始化數據,因此無需提供setter方法
注意:自動裝配建議使用無參構造方法創建對象(默認),如果不提供對應構造方法,請提供唯一的構造方法

3.1.2 使用@Qualifier注解開啟指定名稱裝配bean

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    @Qualifier("bookDao")
    private BookDao bookDao;
} 

注意@Qualifier注解無法單獨使用,必須配合@Autowired注解使用

3.1.3 使用@Value注解實現簡單類型注入

@Repository("bookDao")
public class BookDaoImpl implements BookDao {
    @Value("it_hao528")
    private String name;
    @Override
    public void save() {
        System.out.println("book dao save..." + name);
    }
}

3.2 加載properties文件

3.2.1 使用@PropertySource注解加載properties文件

@Configuration
@ComponentScan({"com.hao"})
@PropertySource({"jdbc.properties"})
public class SpringConfig {
}

注意:路徑僅支持單一文件配置,多文件請使用數組格式配置,不允許使用通配符*

4. 第三方bean管理

這里還是以druid為例。

4.1 第三方bean管理

4.1.1 使用@Bean注解配置第三方bean

  1. 定義一個方法獲得要管理的對象
  2. 添加@Bean,表示當前方法的返回值是一個bean
@Configuration
public class SpringConfig {
    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("123456");
        return ds;
    }
}

4.1.2 使用獨立的配置類管理第三方bean

  1. 創建一個獨立的三方配置類
  2. 定義一個方法獲得要管理的對象
  3. 添加@Bean,表示當前方法的返回值是一個bean
public class JdbcConfig {
    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("hao123456");
        return ds;
    }
}

4.1.3 將獨立的配置類加入核心配置

4.1.3.1 方式一:導入式
public class JdbcConfig {
    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        /* 相關配置 */  
        return ds;
    }
}

使用@Import注解手動加入配置類到核心配置,此注解只能添加一次,多個數據請用數組格式。

@Configuration
@Import({JdbcConfig.class})
public class SpringConfig {
}
4.1.3.2 方式二:掃描式
@Configuration
public class JdbcConfig {
    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        /* 相關配置 */  
        return ds;
    }
}

使用@ComponentScan注解掃描配置類所在的包,加載對應的配置類信息。

@Configuration
@ComponentScan({"com.hao.config", "com.hao.service", "com.hao.dao"})
public class SpringConfig {
}

4.2 第三方bean依賴注入

4.2.1 簡單類型依賴注入

public class JdbcConfig {
    @Value("com.mysql.jdbc.Driver")
    private String driver;
    @Value("jdbc:mysql://localhost:3306/spring_db")
    private String url;
    @Value("root")
    private String username;
    @Value("123456")
    private String password;
    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        return ds;
    }
}

簡單類型注入使用@Value注解給屬性設置數據值。

4.2.2 引用類型依賴注入

public class JdbcConfig {
    @Bean
    public DataSource dataSource(BookDao bookDao) {
        System.out.println(bookDao);
        /* 屬性設置 */
        return ds;
    }
}

引用類型注入只需要為bean定義方法設置形參即可,容器會根據類型自動裝配對象。

5. XML配置與注解配置比較

image.png

總結

以上就是關于Spring注解開發詳解的全部內容。
個人的小觀點:
使用XML配置開發管理比較直觀,所有bean都在配置文件中進行管理,但是如果管理的bean比較多,配置文件代碼會比較多,看起來會比較臃腫。
使用注解開發Java類配置不需要太多代碼,除三方外的所有bean都分散到相應的接口類中使用注解管理,這樣雖然代碼看起來比較清爽,但是管理起來可能會因為比較分散而稍麻煩一些。

如果有什么問題,我們可以一起交流討論解決。

最后,希望可以幫助到有需要的碼友。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容