前言
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供君山網(wǎng)站建設(shè)、君山做網(wǎng)站、君山網(wǎng)站設(shè)計(jì)、君山網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、君山企業(yè)網(wǎng)站模板建站服務(wù),十載君山做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
最近在知乎上面看到一篇關(guān)于程序員面試的問題,面試官問我們一般有幾種注入的方法,這幾種注入的方法分別在什么時(shí)候運(yùn)用比合理,當(dāng)時(shí)我看到這個(gè)時(shí)候懵逼了,由于我自己也是剛剛接觸springboot不久,所以就自己在平時(shí)運(yùn)用的上面總結(jié)了一些知識(shí)點(diǎn)常用的幾種springboot的注入方法,由于我是一個(gè)小萌新,所只要是能夠起道注入的方法的注解我都列出來,有可能會(huì)有錯(cuò),希望大家能夠及時(shí)提出來我來解決:
這幾種常用的嗎?難道還有什么其他的?當(dāng)然有,下面我總結(jié)了一下自己對(duì)于這幾種注入的看法和認(rèn)識(shí)。
首先是我們使用頻率較為高的@Autowired:
這個(gè)注解可能是我們使用頻率較為頻繁的一個(gè)注解的了,幾乎在剛剛?cè)腴T的時(shí)候,我們都會(huì)使用這個(gè)注釋,那么@Autowired 注釋的工作原理是什么呢?
第一:其實(shí)在啟動(dòng)spring IoC時(shí),容器自動(dòng)裝載了一個(gè)AutowiredAnnotationBeanPostProcessor后置處理器,當(dāng)容器掃描到@Autowied、@Resource或@Inject時(shí),就會(huì)在IoC容器自動(dòng)查找需要的bean,并裝配給該對(duì)象的屬性
第二:@Autowired 注釋,它可以對(duì)類成員變量、方法及構(gòu)造函數(shù)進(jìn)行標(biāo)注,完成自動(dòng)裝配的工作。 通過 @Autowired的使用來消除 set ,get方法。在使用@Autowired之前,我們對(duì)一個(gè)bean配置起屬性時(shí),是這用用的
通過這種方式來,配置比較繁瑣,而且代碼比較多。在Spring 2.5 引入了 @Autowired 注釋
我們平常直接引用的時(shí)候很少注意這些,只是自己寫好了一個(gè)方法或者springboot自動(dòng)配置好的一個(gè)方法我們要在另一個(gè)類中去調(diào)用,這個(gè)時(shí)候,我們就會(huì)采用該注釋,例如:我已經(jīng)寫好一個(gè)工具類,此時(shí),我需要在其他類中調(diào)用該工具類的方法:
/* 這是要被調(diào)用的類 */ @Repository("userRepository") public class UserRepositoryImps implements UserRepository{ @Override public void save() { System.out.println("UserRepositoryImps save is success"); } }
已調(diào)用的類
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.proc.bean.repository.UserRepository; /* 方法注入的類 */ @Service public class UserService { @Autowired private UserRepository userRepository; public void save(){ userRepository.save(); } }
接著我們開始聊一下@Resource這個(gè)注解:
第一:@Resource(這個(gè)注解屬于J2EE的),默認(rèn)按照名稱進(jìn)行裝配,名稱可以通過name屬性進(jìn)行指定,如果沒有指定name屬性,當(dāng)注解寫在字段上時(shí),默認(rèn)取字段名進(jìn)行安裝名稱查找,如果注解寫在setter方法上默認(rèn)取屬性名進(jìn)行裝配。當(dāng)找不到與名稱匹配的bean時(shí)才按照類型進(jìn)行裝配。但是需要注意的是,如果name屬性一旦指定,就只會(huì)按照名稱進(jìn)行裝配。
第二:可以用在方法、屬性、類上,通過CommonAnnotationBeanPostProcessor類實(shí)現(xiàn)依賴注入 與@AutoWired一致。但可以指定name屬性來指定beanName,但如果name對(duì)應(yīng)的bean不存在,則會(huì)拋出異常,且沒有required屬性。
當(dāng)作用在類上面的時(shí)候:可以用來指定name
@Resource(name = "testMapper") private TestMapper testMapper;
第三:@Autowired默認(rèn)按類型裝配(這個(gè)注解是屬業(yè)spring的),默認(rèn)情況下必須要求依賴對(duì)象必須存在,如果要允許null 值,可以設(shè)置它的required屬性為false
@Autowired() private StudentDao studentDao;
來,繼續(xù)往下走,開始擼@Component這個(gè)注解:
第一:@Component泛指組件,當(dāng)組件不好歸類的時(shí)候,我們可以使用這個(gè)注解進(jìn)行標(biāo)注。
第二:@component (把普通pojo實(shí)例化到spring容器中,相當(dāng)于配置文件中的
例如下面的這個(gè)例子
注意:這個(gè)只能作用于類上面
package cn.com.scitc.security; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import org.springframework.stereotype.Component; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @Component("myLoginSuccessHandler") public class MyLoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private ObjectMapper objectMapper; @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException { response.setContentType("application/json;charset=UTF-8"); logger.info("登錄成功"); PrintWriter out = response.getWriter(); out.write(objectMapper.writeValueAsString("登錄成功")); out.flush(); out.close(); } }
看了這么多,是不是有點(diǎn)累了,不行接著擼@Configuration的注解:
首先我們先明白從Spring3.0,@Configuration用于定義配置類,可替換xml配置文件,被注解的類內(nèi)部包含有一個(gè)或多個(gè)被@Bean注解的方法,這些方法將會(huì)被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext類進(jìn)行掃描,并用于構(gòu)建bean定義,初始化Spring容器。
在使用的時(shí)候需要注意:
1.@Configuration不可以是final類型;
2.@Configuration不可以是匿名類;
3.嵌套的configuration必須是靜態(tài)類。
下面講解詳細(xì)的使用
第一:用@Configuration加載spring
1.1、@Configuration配置spring并啟動(dòng)spring容器
1.2、@Configuration啟動(dòng)容器+@Bean注冊(cè)Bean
1.3、@Configuration啟動(dòng)容器+@Component注冊(cè)Bean
1.4、使用 AnnotationConfigApplicationContext 注冊(cè) AppContext 類的兩種方法
1.5、配置Web應(yīng)用程序(web.xml中配置AnnotationConfigApplicationContext)
第二:組合多個(gè)配置類
2.1、在@configuration中引入spring的xml配置文件
2.2、在@configuration中引入其它注解配置
2.3、@configuration嵌套(嵌套的Configuration必須是靜態(tài)類)
2.4、@EnableXXX注解
2.5、@Profile邏輯組配置
2.6、使用外部變量
下面講解一個(gè)比較常用的例子:不知道各位大佬的在用在SpringBoot 中使用Security安全框架的時(shí)候會(huì)出現(xiàn)一個(gè)默認(rèn)的登錄界面,但是我們一般不回去用哪個(gè)登錄界面,這時(shí)候我們就應(yīng)該自己去寫一個(gè)登錄的界面以及后端的實(shí)行方法,那么這個(gè)時(shí)候,@configuration就派上用場(chǎng)了,話不多說,直接上例子:
package cn.com.scitc.config; import org.springframework.boot.web.server.ConfigurableWebServerFactory; import org.springframework.boot.web.server.ErrorPage; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; @Configuration public class ErrorConfigurar { /** * 自定義錯(cuò)誤頁(yè)面 * @return */ @Bean public WebServerFactoryCustomizerwebServerFactoryCustomizer() { return (factory -> { ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/404"); ErrorPage errorPage500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,"/500"); ErrorPage errorPage403 = new ErrorPage(HttpStatus.FORBIDDEN,"/403"); factory.addErrorPages(errorPage404); factory.addErrorPages(errorPage403); factory.addErrorPages(errorPage500); }); } }
注意:該注釋也是用于全局的,所以定義在類上面。
接下來來一個(gè)就比較簡(jiǎn)單的@Qualifier了,這個(gè)注解在我認(rèn)為就是@Autowired的小弟,它一般和@Autowired一起用,當(dāng) @Autowired() 不帶參數(shù)的時(shí)候@Qualifie就可以帶上參數(shù)。Qualifier限定描述符除了能根據(jù)名字進(jìn)行注入,更能進(jìn)行更細(xì)粒度的控制如何選擇候選者。
@Autowired() @Qualifie("/studentDao") private StudentDao studentDao;
現(xiàn)在繼續(xù)擼一個(gè)叫@Bean的注解;
很多人就會(huì)問@Bean為什么可以當(dāng)做注入來用呢?在剛剛開始的時(shí)候我也是認(rèn)為@Bean就是封裝一個(gè)POJO類而已,可是后面我覺得它是可以用來當(dāng)做注入注解來使用的。
首先,@Bean可理解為用spring的時(shí)候xml里面的
其次,@Bean是一個(gè)方法級(jí)別上的注解,主要用在@Configuration注解的類里,也可以用在@Component注解的類里,添加的bean的id為方法名;
@Configuration public class AppConfig { @Bean public TransferService transferService() { return new TransferServiceImpl(); } }
再接著:@bean 也可以依賴其他任意數(shù)量的bean,如果TransferService 依賴 AccountRepository,我們可以通過方法參數(shù)實(shí)現(xiàn)這個(gè)依賴;
@Bean public TransferService transferService(AccountRepository accountRepository) { return new TransferServiceImpl(accountRepository); }
最后講一下,指定bean的scope
使用@Scope注解來指定使用@Bean定義的bean
@Scope("prototype")
設(shè)置@Scope的屬性proxyMode來指定,默認(rèn)是ScopedProxyMode.NO, 你可以指定為默認(rèn)是ScopedProxyMode.INTERFACES或者默認(rèn)是ScopedProxyMode.TARGET_CLASS。
@Bean @SessionScope public StuPreferences stuPreferences() { return new StuPreferences(); } @Bean public Service StuService() { StuService service = new SimpleStuService(); service.setStuPreferences(StuPreferences()); return service; }
通過上面的說明,就足以說明這是可以用來注入的。
最后,我們來探討一下private final修飾的變量可以被用來作為注入你們覺得可以嗎?
試想,在一個(gè)大的項(xiàng)目中,幾乎所有的引用都是用public、@Bean等相應(yīng)的方法注入,那么就會(huì)造成代碼的耦合度較高,造成了項(xiàng)目的維護(hù)困難,那么久只有被項(xiàng)目經(jīng)理K一頓啦。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)創(chuàng)新互聯(lián)的支持。