SpringIOC的注解應用方式
? 在之前的項目中,我們都是通過xml文件進行bean或者某些屬性的賦值,其實還有另外一種注解的方式,在企業(yè)開發(fā)中使用的很多,在bean上添加注解,可以快速的將bean注冊到ioc容器。
1、使用注解的方式注冊bean到IOC容器中
applicationContext.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.xsd">
<!--
使用注解需要如下步驟:
1、添加上述四個注解中的任意一個
2、添加自動掃描注解的組件,此操作需要依賴context命名空間
3、添加自動掃描的標簽context:component-scan
注意:當使用注解注冊組件和使用配置文件注冊組件是一樣的,但是要注意:
1、組件的id默認就是組件的類名首字符小寫,如果非要改名字的話,直接在注解中添加即可
2、組件默認情況下都是單例的,如果需要配置多例模式的話,可以在注解下添加@Scope注解
-->
<!--
定義自動掃描的基礎包:
base-package:指定掃描的基礎包,spring在啟動的時候會將基礎包及子包下所有加了注解的類都自動
掃描進IOC容器
-->
<context:component-scan base-package="com.example"></context:component-scan>
</beans>PersonController.java
package com.example.controller;
import org.springframework.stereotype.Controller;
@Controller
public class PersonController {
public PersonController() {
System.out.println("創(chuàng)建對象");
}
}PersonService.java
package com.exxample.service;
import org.springframework.stereotype.Service;
@Service
public class PersonService {
}PersonDao.java
package com.example.dao;
import org.springframework.stereotype.Repository;
@Repository("personDao")
@Scope(value="prototype")//默認singleton,改為prototype
public class PersonDao {
}如果想要將自定義的bean對象添加到IOC容器中,需要在類上添加某些注解
Spring中包含4個主要的組件添加注解:
- @Controller:控制器,推薦給controller層添加此注解
- @Service:業(yè)務邏輯,推薦給業(yè)務邏輯層添加此注解
- @Repository:倉庫管理,推薦給數(shù)據(jù)訪問層添加此注解
- @Component:給不屬于以上基層的組件添加此注解
注意:我們雖然人為的給不同的層添加不同的注解,但是在spring看來,可以在任意層添加任意注解,但spring底層是不會給具體的層次驗證注解,這樣寫的目的只是為了提高可讀性,最偷懶的方式就是給所有想交由IOC容器管理的bean對象添加component注解
2、定義掃描包時要包含的類和不要包含的類
? 當定義好基礎的掃描包后,在某些情況下可能要有選擇性的配置是否要注冊bean到IOC容器中,此時可以通過如下的方式進行配置。
applicationContext.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.xsd">
<context:component-scan base-package="com.example" use-default-filters="false">
<!--
當定義好基礎掃描的包之后,可以排除包中的某些類,使用如下的方式:
type:表示指定過濾的規(guī)則
annotation:按照注解進行排除,標注了指定注解的組件不要,expression表示要過濾的注解
assignable:指定排除某個具體的類,按照類排除,expression表示不注冊的具體類名
aspectj:aop使用的aspectj表達式,一般不用
custom:定義一個typeFilter,自己寫代碼決定哪些類被過濾掉,一般不用
regex:使用正則表達式過濾,一般不用
-->
<!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
<!--指定只掃描哪些組件,默認情況下是全部掃描的,所以此時要配置的話需要在component-scan標簽中添加 use-default-filters="false"-->
<context:include-filter type="assignable" expression="com.example.service.PersonService"/>
</context:component-scan>
</beans>3、使用@AutoWired進行自動注入
? 使用注解的方式實現(xiàn)自動注入需要使用@AutoWired注解。
PersonController.java
package com.example.controller;
import com.example.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class PersonController {
@Autowired
private PersonService personService;
public PersonController() {
System.out.println("創(chuàng)建對象");
}
public void getPerson(){
personService.getPerson();
}
}PersonService.java
package com.example.service;
import com.example.dao.PersonDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PersonService {
@Autowired
private PersonDao personDao;
public void getPerson(){
personDao.getPerson();
}
}PersonDao.java
package com.example.dao;
import org.springframework.stereotype.Repository;
@Repository
public class PersonDao {
public void getPerson(){
System.out.println("PersonDao:getPerson");
}
}注意:當使用AutoWired注解的時候,自動裝配的時候是根據(jù)類型實現(xiàn)的。
? 1、如果只找到一個,則直接進行賦值,
? 2、如果沒有找到,則直接拋出異常,
? 3、如果找到多個,那么會按照變量名作為id繼續(xù)匹配,
- 匹配上直接進行裝配
- 如果匹配不上則直接報異常
PersonServiceExt.java
package com.example.service;
import com.example.dao.PersonDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PersonServiceExt extends PersonService{
@Autowired
private PersonDao personDao;
public void getPerson(){
System.out.println("PersonServiceExt......");
personDao.getPerson();
}
}PersonController.java
package com.example.controller;
import com.example.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class PersonController {
@Autowired
private PersonService personServiceExt;
public PersonController() {
System.out.println("創(chuàng)建對象");
}
public void getPerson(){
personServiceExt.getPerson();
}
}? 還可以使用@Qualifier注解來指定id的名稱,讓spring不要使用變量名,當使用@Qualifier注解的時候也會有兩種情況:
? 1、找到,則直接裝配
? 2、找不到,就會報錯
PersonController.java
package com.example.controller;
import com.example.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
@Controller
public class PersonController {
@Autowired
@Qualifier("personService")
private PersonService personServiceExt2;
public PersonController() {
System.out.println("創(chuàng)建對象");
}
public void getPerson(){
personServiceExt2.getPerson();
}
}? 通過上述的代碼我們能夠發(fā)現(xiàn),使用@AutoWired肯定是能夠裝配上的,如果裝配不上就會報錯。
4、@AutoWired可以進行定義在方法上
? 當我們查看@AutoWired注解的源碼的時候發(fā)現(xiàn),此注解不僅可以使用在成員變量上,也可以使用在方法上。
PersonController.java
package com.example.controller;
import com.example.dao.PersonDao;
import com.example.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
@Controller
public class PersonController {
@Qualifier("personService")
@Autowired
private PersonService personServiceExt2;
public PersonController() {
System.out.println("創(chuàng)建對象");
}
public void getPerson(){
System.out.println("personController..."+personServiceExt2);
// personServiceExt2.getPerson();
}
/**
* 當方法上有@AutoWired注解時:
* 1、此方法在bean創(chuàng)建的時候會自動調(diào)用
* 2、這個方法的每一個參數(shù)都會自動注入值
* @param personDao
*/
@Autowired
public void test(PersonDao personDao){
System.out.println("此方法被調(diào)用:"+personDao);
}
/**
* @Qualifier注解也可以作用在屬性上,用來被當作id去匹配容器中的對象,如果沒有
* 此注解,那么直接按照類型進行匹配
* @param personService
*/
@Autowired
public void test2(@Qualifier("personServiceExt") PersonService personService){
System.out.println("此方法被調(diào)用:"+personService);
}
}5、自動裝配的注解@AutoWired,@Resource
? 在使用自動裝配的時候,出了可以使用@AutoWired注解之外,還可以使用@Resource注解。
? 1、@AutoWired:是spring中提供的注解,@Resource:是jdk中定義的注解,依靠的是java的標準
? 2、@AutoWired默認是按照類型進行裝配,默認情況下要求依賴的對象必須存在,@Resource默認是按照名字進行匹配的,同時可以指定name屬性。
? 3、@AutoWired只適合spring框架,而@Resource擴展性更好
PersonController.java
package com.example.controller;
import com.example.dao.PersonDao;
import com.example.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class PersonController {
@Qualifier("personService")
@Resource
private PersonService personServiceExt2;
public PersonController() {
System.out.println("創(chuàng)建對象");
}
public void getPerson(){
System.out.println("personController..."+personServiceExt2);
personServiceExt2.getPerson();
}
/**
* 當方法上有@AutoWired注解時:
* 1、此方法在bean創(chuàng)建的時候會自動調(diào)用
* 2、這個方法的每一個參數(shù)都會自動注入值
* @param personDao
*/
@Autowired
public void test(PersonDao personDao){
System.out.println("此方法被調(diào)用:"+personDao);
}
/**
* @Qualifier注解也可以作用在屬性上,用來被當作id去匹配容器中的對象,如果沒有
* 此注解,那么直接按照類型進行匹配
* @param personService
*/
@Autowired
public void test2(@Qualifier("personServiceExt") PersonService personService){
System.out.println("此方法被調(diào)用:"+personService);
}
}6、泛型依賴注入
? 為了了解泛型依賴注入,首先我們需要先寫一個基本的案例:
Student.java
package com.example.bean;
public class Student {
}Teacher.java
package com.example.bean;
public class Teacher {
}BaseDao.java
package com.example.dao;
import org.springframework.stereotype.Repository;
@Repository
public abstract class BaseDao<T> {
public abstract void save();
}StudentDao.java
package com.example.dao;
import com.example.bean.Student;
import org.springframework.stereotype.Repository;
@Repository
public class StudentDao extends BaseDao<Student>{
public void save() {
System.out.println("保存學生");
}
}TeacherDao.java
package com.example.dao;
import com.example.bean.Teacher;
import org.springframework.stereotype.Repository;
@Repository
public class TeacherDao extends BaseDao<Teacher> {
public void save() {
System.out.println("保存老師");
}
}StudentService.java
package com.example.service;
import com.example.dao.StudentDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class StudentService {
@Autowired
private StudentDao studentDao;
public void save(){
studentDao.save();
}
}TeacherService.java
package com.example.service;
import com.example.dao.TeacherDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class TeacherService {
@Autowired
private TeacherDao teacherDao;
public void save(){
teacherDao.save();
}
}MyTest.java
import com.example.service.StudentService;
import com.example.service.TeacherService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.sql.DataSource;
import java.sql.SQLException;
public class MyTest {
public static void main(String[] args) throws SQLException {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
StudentService studentService = context.getBean("studentService",StudentService.class);
studentService.save();
TeacherService teacherService = context.getBean("teacherService",TeacherService.class);
teacherService.save();
}
}? 上述代碼可以完成對應的功能,但是Service層的代碼能夠改寫成:
BaseService.java
package com.example.service;
import com.example.dao.BaseDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
public class BaseService<T> {
@Autowired
BaseDao<T> baseDao;
public void save(){
System.out.println("自動注入的對象:"+baseDao);
baseDao.save();
}
}StudentService.java
package com.example.service;
import com.example.bean.Student;
import com.example.dao.StudentDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class StudentService extends BaseService<Student> {
}TeacherService.java
package com.example.service;
import com.example.bean.Teacher;
import com.example.dao.TeacherDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class TeacherService extends BaseService<Teacher>{
}總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
解決Spring Cloud Gateway獲取body內(nèi)容,不影響GET請求的操作
這篇文章主要介紹了解決Spring Cloud Gateway獲取body內(nèi)容,不影響GET請求的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12
java 將jsonarray 轉(zhuǎn)化為對應鍵值的jsonobject方法
下面小編就為大家分享一篇java 將jsonarray 轉(zhuǎn)化為對應鍵值的jsonobject方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03
javaweb學習總結(jié)——使用JDBC處理MySQL大數(shù)據(jù)
本篇文章主要介紹了JDBC處理MySQL大數(shù)據(jù),有時是需要用程序把大文本或二進制數(shù)據(jù)直接保存到數(shù)據(jù)庫中進行儲存的,非常具有實用價值,需要的朋友可以參考下。2016-11-11

