日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

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

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

關注公眾號領取海量架構師資料

環境搭建

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

準備所需Jar包

Spring注解之組件注冊

Spring提供了許多的注解配置,這樣我們就可以通過注解的方式實現組件的注冊,下圖就是Spring中經常使用到的注解。?

@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來標注該類為Spring中的配置類,@ComponentScan(“model”)是為該配置類指定要去掃描的參數。

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

@Component

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

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

配置類

/** * @Configurable: 該注解是標注該類是配置類 * @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注冊類里標注,創建對象的方法,可以通過一個返回值為該對象的方法去創建該對象,并通過構造器為該對象的屬性進行賦值。

// 配置類@Configurable@ComponentScan("model")public class MainConfig { // 默認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注解 是通過設置條件來過濾一些資源,我們可以過濾一些資源不讓它加載到ioc容器中。它的使用要在@ComponentScan這個注解中國去使用,通過excludeFilters參數傳值,excludeFilters是一個數組,可以設定多個@TypeFilter。

@TypeFilter語法

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

@FilterType.CUSTOM自定義規則

使用自定義規則,我們必須給它創建一個制定規則的類,這個類要去實現TypeFilter這個接口,并實現match這個方法,過濾器就會根據match方法的返回值加載,如果去ture就去過濾不滿足條件的,如果為false則不會去加載!

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

@Scope

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

各作用域的的作用

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

案例演示

singleton

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

測試代碼

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

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

Layz-bean

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

使用語法

// 配置類@Configurable@ComponentScan("model")public class MainConfig { /** * 懶加載: * 針對的是單實例的bean,默認在容器啟動的時候創建對象 * 賴加載:容器啟動時不創建對象,當第一次被調用時被創建 * */ @Lazy @Bean public Product product() { System.out.println("該實例已被創建"); return new Product("張三","hashd",1);????}???

測試

@Conditional

@Conditional注解是根據制定條件來進行注冊,需要我創建配置條件的配置類,如果條件滿足就進行注冊,不滿足就不去注冊。

語法

配置類

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

條件類必須去實現Condition接口,并添加為實現的方法!

public class winCondition implements Condition{ @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; }}

案例

需求根據當前操作系統去注冊組件。

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

條件配置類

public class winCondition implements Condition{ // Windows系統,返回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: 判斷條件能使用上下文環境 * AnnotatedTypeMetadata: 注釋信息 */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // 是否Linux系統 // 1、能獲取到ioc使用的bean工廠 ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); // 2、獲取類加載器 ClassLoader clLoader = context.getClassLoader(); // 3、獲取當前環境信息 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通過快速導入的方式實現把實例加入spring的IOC容器中

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

  • @Import注解有三種用法

第一種用法:直接填class數組

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

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

第二種用法:ImportSelector方式【重點】

這種方式的前提就是一個類要實現ImportSelector接口,假如我要用這種方法,目標對象是Myclass這個類,分析具體如下:創建Myclass類并實現ImportSelector接口

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

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

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

第二步:編寫TestDemo 類,并標注上使用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); //這里的參數代表要做操作的類 String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames(); for (String name : beanDefinitionNames){ System.out.println(name);????????} }}

第三種用法:ImportBeanDefinitionRegistrar方式

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

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

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

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

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

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

@FactoryBean

編寫配置類

// 標記這是一個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,實際上就是工廠Bean(MyFactoryBean通過getObject()方法返回的對象) Object factoryBean01 = context.getBean("factoryBean"); System.out.println("實際上注入到容器中的類型是:" + factoryBean01.getClass()); Object factoryBean02 = context.getBean("factoryBean"); System.out.println("注入到容器內的對象是否是單例:" + (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); } }}

最后

感謝你看到這里,文章有什么不足還請指正,覺得文章對你有幫助的話記得給我點個贊,每天都會分享java相關技術文章或行業資訊,歡迎大家關注和轉發文章!

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。