日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

注解赋值可以是方法_P7笔记,把Spring注解讲的明明白白

發(fā)布時(shí)間:2025/3/20 javascript 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 注解赋值可以是方法_P7笔记,把Spring注解讲的明明白白 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

關(guān)注公眾號領(lǐng)取海量架構(gòu)師資料

環(huán)境搭建

注解的方式是通過配置類的方式來注入組件,注解注入要比XML注入的方式簡單,注解注入也需要在前者的基礎(chǔ)上,添加一個(gè)spring-context的包,也是實(shí)際開發(fā)中常用的方式。

準(zhǔn)備所需Jar包

Spring注解之組件注冊

Spring提供了許多的注解配置,這樣我們就可以通過注解的方式實(shí)現(xiàn)組件的注冊,下圖就是Spring中經(jīng)常使用到的注解。?

@ComponentScan和@Configurable

原先xml的方式

<?xml version="1.0" encoding="UTF-8"?><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="model">context:component-scan>beans>

使用配置類?@Configurable來標(biāo)注該類為Spring中的配置類,@ComponentScan(“model”)是為該配置類指定要去掃描的參數(shù)。

package config;import org.springframework.beans.factory.annotation.Configurable;import org.springframework.context.annotation.ComponentScan;import model.Product;/** * @Configurable: 該注解是標(biāo)注該類是配置類 * @ComponentScan:配置要掃描的包 * @author GaoYang */@Configurable@ComponentScan("model")public class MainConfig {}

@Component

使用該注解就可以將Java對象@Component注冊到Ioc容器中,@Component注解要是給屬性賦值要配合@Value注解為屬性賦值。

/** @Componnt可以指定該對象的id,也可以不用指定 默認(rèn)id為該類的類名首字母小寫 */@Component("students")public class Student { @Value("01") private int sid; @Value("侯寧寧") private String name; @Value("男")????private?String?sex;

配置類

/** * @Configurable: 該注解是標(biāo)注該類是配置類 * @ComponentScan:配置要掃描的包 * @author GaoYang */@Configurable@ComponentScan("model")public?class?MainConfig?{}

使用@Configuration注入

@Component("students")public class Student { @Value("01") private int sid; @Value("侯寧寧") private String name; @Value("男") private String sex; public Student() { super(); } public Student(int sid, String name, String sex) { super(); this.sid = sid; this.name = name; this.sex = sex; } public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "Student [sid=" + sid + ", name=" + name + ", sex=" + sex + "]";????}}

測試?

@Bean

使用@Bean注解該可以在我們的spring注冊類里標(biāo)注,創(chuàng)建對象的方法,可以通過一個(gè)返回值為該對象的方法去創(chuàng)建該對象,并通過構(gòu)造器為該對象的屬性進(jìn)行賦值。

// 配置類@Configurable@ComponentScan("model")public class MainConfig { // 默認(rèn)id為方法名 @Bean public Product product1() { return new Product("張三","hashd",1); } // 可以指定id @Bean("product2") public Product product2() { return new Product("張三","hashd",1); }}

Java-Bean對象

public class Product { private String name; private String price; private int num; public Product() { super(); } public Product(String name, String price, int num) { super(); this.name = name; this.price = price; this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } @Override public String toString() { return "Product [name=" + name + ", price=" + price + ", num=" + num + "]"; }}

測試

@TypeFilter

@TypeFilter注解 是通過設(shè)置條件來過濾一些資源,我們可以過濾一些資源不讓它加載到ioc容器中。它的使用要在@ComponentScan這個(gè)注解中國去使用,通過excludeFilters參數(shù)傳值,excludeFilters是一個(gè)數(shù)組,可以設(shè)定多個(gè)@TypeFilter。

@TypeFilter語法

@Configurable@ComponentScan(value = "model",excludeFilters = { // FilterType.ANNOTATION是通過注解的形式進(jìn)行過濾 @Filter(type = FilterType.ANNOTATION,classes = {Controller.class}), // FilterType.ASSIGNABLE_TYPE 是通過給定的類型 @Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Product.class}), // FilterType.ASPECTJ 根據(jù)正則表達(dá)式 @Filter(type = FilterType.ASPECTJ,classes = {""}), // FilterType.CUSTOM 使用自定義規(guī)則 @Filter(type = FilterType.CUSTOM,classes = {TypeFilterImp.class})})public class MainConfig {????//?@Bean?==?}

@FilterType.CUSTOM自定義規(guī)則

使用自定義規(guī)則,我們必須給它創(chuàng)建一個(gè)制定規(guī)則的類,這個(gè)類要去實(shí)現(xiàn)TypeFilter這個(gè)接口,并實(shí)現(xiàn)match這個(gè)方法,過濾器就會(huì)根據(jù)match方法的返回值加載,如果去ture就去過濾不滿足條件的,如果為false則不會(huì)去加載!

/** * MetadataReader:讀取到的當(dāng)前正在掃描的信息 * MetadataReaderFactory:可以獲取到其他任何類的信息 */ @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { // 獲取當(dāng)前類注解的信息 AnnotationMetadata mr = metadataReader.getAnnotationMetadata(); // 獲取當(dāng)前正在掃描的類的信息 ClassMetadata classMetadata = metadataReader.getClassMetadata(); // 獲取當(dāng)前類的資源信息 Resource resource = metadataReader.getResource(); // 獲取當(dāng)前類的名字 String className = classMetadata.getClassName(); System.out.println("----"+className); // contains包含“er” if(className.contains("er")) { return true; } return false; }}

@Scope

Spring創(chuàng)建對象默認(rèn)是單例的,使用@Scope來描述也就是scope=“singleton”,另外scope還有prototype、request、session、global session作用域。

各作用域的的作用

singleton單例模式,全局有且僅有一個(gè)實(shí)例。(默認(rèn)值)prototype原型模式,每次獲取Bean的時(shí)候會(huì)有一個(gè)新的實(shí)例。request表示該針對每一次HTTP請求都會(huì)產(chǎn)生一個(gè)新的bean,同時(shí)該bean僅在當(dāng)前HTTP request內(nèi)有效,配置實(shí)例:request、session、global session使用的時(shí)候首先要在初始化web的web.xml中做如下配置:如果你使用的是Servlet 2.4及以上的web容器,那么你僅需要在web應(yīng)用的XML聲明文件web.xml中增加下述ContextListener即可: ... class>org.springframework.web.context.request.RequestContextListener ...session作用域表示該針對每一次HTTP請求都會(huì)產(chǎn)生一個(gè)新的bean,同時(shí)該bean僅在當(dāng)前HTTP session內(nèi)有效global?session作用域類似于標(biāo)準(zhǔn)的HTTP?Session作用域,不過它僅僅在基于portlet的web應(yīng)用中才有意義。Portlet規(guī)范定義了全局Session的概念,它被所有構(gòu)成某個(gè)?portlet?web應(yīng)用的各種不同的portlet所共享。在global?session作用域中定義的bean被限定于全局portlet?Session的生命周期范圍內(nèi)。如果你在web中使用global?session作用域來標(biāo)識bean,那么web會(huì)自動(dòng)當(dāng)成session類型來使用。

案例演示

singleton

@Configurable@ComponentScan("model")public class MainConfig { /** * @Scope * prototype: 多實(shí)例的 @Scope("prototype") * singleton: 單實(shí)例的 @Scope("person") * request: 一次請求創(chuàng)建一個(gè)實(shí)例 * session: 同一個(gè)session創(chuàng)建一個(gè)實(shí)例 * @return */ @Scope("singleton") @Bean public Product product() { System.out.println("該實(shí)例已被創(chuàng)建"); return new Product("張三","hashd",1); }}

測試代碼

public class text { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class); System.out.println("Ioc容器已創(chuàng)建完成!"); Product bean1 = applicationContext.getBean(Product.class); Product bean2 = applicationContext.getBean(Product.class); System.out.println(bean1== bean2); }}

從下圖可以看到,bean1 == bean2?

Layz-bean

@Layz賴加載主要是針對的是單例模式下,單例模式下ioc容器初始化時(shí),就將bean對象注入到了容器中,@Layz注解可以讓容器創(chuàng)建時(shí)不去注冊容器,而是等到第一次調(diào)用時(shí)才去注冊bean對象。此時(shí),創(chuàng)建的對象依然是單例模式!

使用語法

// 配置類@Configurable@ComponentScan("model")public class MainConfig { /** * 懶加載: * 針對的是單實(shí)例的bean,默認(rèn)在容器啟動(dòng)的時(shí)候創(chuàng)建對象 * 賴加載:容器啟動(dòng)時(shí)不創(chuàng)建對象,當(dāng)?shù)谝淮伪徽{(diào)用時(shí)被創(chuàng)建 * */ @Lazy @Bean public Product product() { System.out.println("該實(shí)例已被創(chuàng)建"); return new Product("張三","hashd",1);????}???

測試

@Conditional

@Conditional注解是根據(jù)制定條件來進(jìn)行注冊,需要我創(chuàng)建配置條件的配置類,如果條件滿足就進(jìn)行注冊,不滿足就不去注冊。

語法

配置類

@Configurablepublic class MainConfig { @Conditional({winCondition.class}) @Bean("wind") public Product wind() { System.out.println("該實(shí)例已被創(chuàng)建"); return new Product("張三","wind",1);}???

條件類必須去實(shí)現(xiàn)Condition接口,并添加為實(shí)現(xiàn)的方法!

public class winCondition implements Condition{ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata arg1) { Environment environment = context.getEnvironment(); // 獲取當(dāng)前操作系統(tǒng)的名字 String property = environment.getProperty("os.name"); if(property.contains("Windows")) { return true; } return false; }}

案例

需求根據(jù)當(dāng)前操作系統(tǒng)去注冊組件。

// 配置類@Configurable@Import(Hero.class)public class MainConfig { // Windows系統(tǒng) @Conditional({winCondition.class}) @Bean("wind") public Product wind() { System.out.println("該實(shí)例已被創(chuàng)建"); return new Product("張三","wind",1); } // Linux系統(tǒng) @Conditional({linuxCondition.class}) @Bean("linux") public Product linux() {????????return?new?Product("李四","linux",2);????}}

條件配置類

public class winCondition implements Condition{ // Windows系統(tǒng),返回true @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata arg1) { Environment environment = context.getEnvironment(); String property = environment.getProperty("os.name"); if(property.contains("Windows")) { return true; } return false;????}}public class linuxCondition implements Condition{ /** * ConditionContext: 判斷條件能使用上下文環(huán)境 * AnnotatedTypeMetadata: 注釋信息 */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // 是否Linux系統(tǒng) // 1、能獲取到ioc使用的bean工廠 ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); // 2、獲取類加載器 ClassLoader clLoader = context.getClassLoader(); // 3、獲取當(dāng)前環(huán)境信息 Environment environment = context.getEnvironment(); String property = environment.getProperty("os.name"); // 5、bean注冊類 BeanDefinitionRegistry registry = context.getRegistry(); if(property.contains("Linux")) { return true;??????????} return false;}

測試…?

@import

  • @Import只能用在類上 ,@Import通過快速導(dǎo)入的方式實(shí)現(xiàn)把實(shí)例加入spring的IOC容器中

  • 加入IOC容器的方式有很多種,@Import注解就相對很牛皮了,@Import注解可以用于導(dǎo)入第三方包 ,當(dāng)然@Bean注解也可以,但是@Import注解快速導(dǎo)入的方式更加便捷

  • @Import注解有三種用法

第一種用法:直接填class數(shù)組

直接填對應(yīng)的class數(shù)組,class數(shù)組可以有0到多個(gè)。對應(yīng)的import的bean都將加入到spring容器中,這些在容器中bean名稱是該類的全類名 ,比如com.yc.類名

@Import({ 類名.class , 類名.class... })public?class?TestDemo?{}

第二種用法:ImportSelector方式【重點(diǎn)】

這種方式的前提就是一個(gè)類要實(shí)現(xiàn)ImportSelector接口,假如我要用這種方法,目標(biāo)對象是Myclass這個(gè)類,分析具體如下:創(chuàng)建Myclass類并實(shí)現(xiàn)ImportSelector接口

public class Myclass implements ImportSelector {//既然是接口肯定要實(shí)現(xiàn)這個(gè)接口的方法 @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[0]; }}//?分析實(shí)現(xiàn)接口的selectImports方法中的:// 1、返回值:就是我們實(shí)際上要導(dǎo)入到容器中的組件全類名【重點(diǎn) 】// 2、參數(shù):AnnotationMetadata表示當(dāng)前被@Import注解給標(biāo)注的所有注解信息【不是重點(diǎn)】//?需要注意的是selectImports方法可以返回空數(shù)組但是不能返回null,否則會(huì)報(bào)空指針異常!

以上分析完畢之后,具體用法步驟如下:第一步:創(chuàng)建Myclass類并實(shí)現(xiàn)ImportSelector接口,這里用于演示就添加一個(gè)全類名給其返回值

public class Myclass implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{"com.yc.Test.TestDemo3"}; }}

第二步:編寫TestDemo 類,并標(biāo)注上使用ImportSelector方式的Myclass類

@Import({TestDemo2.class,Myclass.class})public class TestDemo { @Bean public AccountDao2 accountDao2(){ return new AccountDao2();????????}}

第三步:編寫打印容器中的組件測試類

** * 打印容器中的組件測試 */public class AnnotationTestDemo { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(TestDemo.class); //這里的參數(shù)代表要做操作的類 String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames(); for (String name : beanDefinitionNames){ System.out.println(name);????????} }}

第三種用法:ImportBeanDefinitionRegistrar方式

同樣是一個(gè)接口,類似于第二種ImportSelector用法,相似度80%,只不過這種用法比較自定義化注冊,具體如下:

public class Myclass2 implements ImportBeanDefinitionRegistrar {//該實(shí)現(xiàn)方法默認(rèn)為空 @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { }}//?參數(shù)分析:// 第一個(gè)參數(shù):annotationMetadata 和之前的ImportSelector參數(shù)一樣都是表示當(dāng)前被@Import注解給標(biāo)注的所有注解信息//?第二個(gè)參數(shù)表示用于注冊定義一個(gè)bean

第二步:編寫代碼,自定義注冊bean

public class Myclass2 implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { //指定bean定義信息(包括bean的類型、作用域...) RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestDemo4.class); //注冊一個(gè)bean指定bean名字(id) beanDefinitionRegistry.registerBeanDefinition("TestDemo4444",rootBeanDefinition); }}

第三步:編寫TestDemo 類,并標(biāo)注上使用ImportBeanDefinitionRegistrar方式的Myclass2類

@Import({TestDemo2.class,Myclass.class,Myclass2.class})public class TestDemo { @Bean public AccountDao2 accountDao222(){ return new AccountDao2(); }}

@FactoryBean

編寫配置類

// 標(biāo)記這是一個(gè)Spring配置類@Configurationpublic class SpringConfiguration { // 如果沒有@Bean注解,則注入到容器中的id就是方法名(也就是myFactoryBean),但是如果顯示的給了值,那么注入到容器中的就是factoryBean @Bean("factoryBean") public MyFactoryBean myFactoryBean(){ return new MyFactoryBean(); }}

測試類

public class SpringDemo { @Test public void springTest01() throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class); // 容器中獲取的Bean,實(shí)際上就是工廠Bean(MyFactoryBean通過getObject()方法返回的對象) Object factoryBean01 = context.getBean("factoryBean"); System.out.println("實(shí)際上注入到容器中的類型是:" + factoryBean01.getClass()); Object factoryBean02 = context.getBean("factoryBean"); System.out.println("注入到容器內(nèi)的對象是否是單例:" + (factoryBean01 == factoryBean02)); Object factoryBean03 = context.getBean("&factoryBean"); System.out.println("如果想獲取到MyFactoryBean的對象,使用&前綴:" + factoryBean03); // 輸出打印Spring中的所有Bean名稱 String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) { System.out.println(beanDefinitionName); } }}

最后

感謝你看到這里,文章有什么不足還請指正,覺得文章對你有幫助的話記得給我點(diǎn)個(gè)贊,每天都會(huì)分享java相關(guān)技術(shù)文章或行業(yè)資訊,歡迎大家關(guān)注和轉(zhuǎn)發(fā)文章!

總結(jié)

以上是生活随笔為你收集整理的注解赋值可以是方法_P7笔记,把Spring注解讲的明明白白的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。