@import_link与@import区别 - CSDN
精华内容
参与话题
  • 1、@Import注解须知 1、@Import只能用在类上,@Import通过快速导入的方式实现把实例加入spring的IOC容器中 2、加入IOC容器的方式有很多种,@Import注解就相对很牛皮了,@Import注解可以用于导入第三方包,当然@...

    1、@Import注解须知

    1、@Import只能用在类上 ,@Import通过快速导入的方式实现把实例加入spring的IOC容器中

     

    2、加入IOC容器的方式有很多种,@Import注解就相对很牛皮了,@Import注解可以用于导入第三方包 ,当然@Bean注解也可以,但是@Import注解快速导入的方式更加便捷

     

    3、@Import注解有三种用法

    2、@Import的三种用法

    @Import的三种用法主要包括:

    1、直接填class数组方式
    2、ImportSelector方式【重点】
    3、ImportBeanDefinitionRegistrar方式

    2.1、第一种用法:直接填class数组

    直接填对应的class数组,class数组可以有0到多个。

    语法如下:

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

    对应的import的bean都将加入到spring容器中,这些在容器中bean名称是该类的全类名 ,比如com.yc.类名

    2.2、第二种用法: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();
            }
    
    }
    

    可以看出,宜春故意挑了个龙套角色@Bean注解

    第三步:编写打印容器中的组件测试类

    /**
     * 打印容器中的组件测试
     */
    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);
            }
    
        }
    }
    

    第四步:运行结果
    在这里插入图片描述

    2.3、第三种用法:ImportBeanDefinitionRegistrar方式

    同样是一个接口,类似于第二种ImportSelector用法,相似度80%,只不过这种用法比较自定义化注册,具体如下:

    第一步:创建Myclass2类并实现ImportBeanDefinitionRegistrar接口

    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();
            }
    
    }
    

    第四步:运行结果
    在这里插入图片描述

    3、@Import注解的三种使用方式总结

    第一种用法:@Import({ 要导入的容器中的组件 } ):容器会自动注册这个组件,id默认是全类名

     

    第二种用法:ImportSelector:返回需要导入的组件的全类名数组,springboot底层用的特别多【重点 】

     

    第三种用法:ImportBeanDefinitionRegistrar:手动注册bean到容器

    以上三种用法方式皆可混合在一个@Import中使用,特别注意第一种和第二种都是以全类名的方式注册,而第三中可自定义方式。

    @Import注解本身在springboot中用的很多,特别是其中的第二种用法ImportSelector方式在springboot中使用的特别多,尤其要掌握!

    展开全文
  • @Import注解的作用

    千次阅读 2020-06-04 11:03:04
    这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、...

    1.简介

    在平时看源码或者很多配置类上面都会出现@Import注解,功能就是和Spring XML 里面 的 一样. @Import注解是用来导入配置类或者一些需要前置加载的类.

    2.源码解析

    2.1 导入配置的三种类型

    @Import支持 三种方式
    1.带有@Configuration的配置类(4.2 版本之前只可以导入配置类,4.2版本之后 也可以导入 普通类)
    2.ImportSelector 的实现
    3.ImportBeanDefinitionRegistrar 的实现

    2.2 源码解释

    /**
     * Indicates one or more {@link Configuration @Configuration} classes to import.
     * 
     *功能类似XML 里面的 <import/> ,可以导入 @Configuration配置类,ImportSelector、
     * ImportBeanDefinitionRegistrar 的实现,4.2 版本之后可以导入普通类(类似AnnotationConfigApplicationContext#register
     * )
     * <p>Provides functionality equivalent to the {@code <import/>} element in Spring XML.
     * Allows for importing {@code @Configuration} classes, {@link ImportSelector} and
     * {@link ImportBeanDefinitionRegistrar} implementations, as well as regular component
     * classes (as of 4.2; analogous to {@link AnnotationConfigApplicationContext#register}).
     *
     * 可以在类级别声明或作为元注释声明
     * <p>May be declared at the class level or as a meta-annotation.
     * 如需要引入XML或其他类型的文件,使用@ImportResource注解
     * <p>If XML or other non-{@code @Configuration} bean definition resources need to be
     * imported, use the {@link ImportResource @ImportResource} annotation instead.
     */
     @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Import {
    
    	/**
    	 * {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
    	 * or regular component classes to import.
    	 */
    	Class<?>[] value();
    
    }
    

    3、测试例子

    3.1 导入普通类

    1. 新建一个TestA
    public class TestA {
    
        public void fun(String str) {
            System.out.println(str);
        }
    
        public void printName() {
            System.out.println("类名 :" + Thread.currentThread().getStackTrace()[1].getClassName());
        }
    }
    
    1. 新建一个ImportConfig,在类上面加上@Configuration,加上@Configuration是为了能让Spring 扫描到这个类,并且直接通过@Import引入TestA类
    @Import({TestA.class})
    @Configuration
    public class ImportConfig {
    }
    

    3.测试结果
    TestA 是一个普通的类,现在可以被@Autowired注释然后调用,就直接说明已经被Spring 注入并管理了,普通的类都是需要先实例化

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ApplicationMain.class)
    public class ImportAnnotionTest {
    
        @Autowired
        TestA testA;
    
        @Test
        public void TestA() {
            testA.printName();
        }
    }
    

    打印:

    类名 :com.test.importdemo.TestA
    

    3.2 导入带有@Configuration的配置类

    1. 新建TestB
    @Configuration
    public class TestB {
        public void fun(String str) {
            System.out.println(str);
        }
    
        public void printName() {
            System.out.println("类名 :" + Thread.currentThread().getStackTrace()[1].getClassName());
        }
    }
    
    1. 在ImportConfig.class里面直接引入TestB
    @Import({TestA.class,TestB.class})
    @Configuration
    public class ImportConfig {
    }
    

    3.测试结果
    TestB.class 的类上面已经有了@Configuration注解,本身就会配spring扫到并实例,@import引入带有@Configuration的配置文件,是需要先实例这个配置文件再进行相关操作

       @Autowired
        TestB testB;
    
    
        @Test
        public void TestB(){
            testB.printName();
        }
    

    打印:

    ImportAnnotionTest in 8.149 seconds (JVM running for 10.104)
    类名 :com.test.importdemo.TestB
    2019-01-31 14:12:05.737  INFO 23760 --- [       Thread-2]
    

    3.3 通过ImportSelector 方式导入的类

    1. 新建TestC.class
    public class TestC {
        public void fun(String str) {
            System.out.println(str);
        }
    
        public void printName() {
            System.out.println("类名 :" + Thread.currentThread().getStackTrace()[1].getClassName());
        }
    }
    

    2.新建SelfImportSelector.class 实现ImportSelector 接口,注入TestC.class
    //TODO ImportSelector 相关解释

    public class SelfImportSelector implements ImportSelector {
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            return new String[]{"com.test.importdemo.TestC"};
        }
    }
    

    3.ImportConfig上面引入SelfImportSelector.class

    @Import({TestA.class,TestB.class,SelfImportSelector.class})
    @Configuration
    public class ImportConfig {
    }
    

    4.测试结果

        @Autowired
        TestC testC;
    
        @Test
        public void TestC() {
            testC.printName();
        }
    

    打印:

    ImportAnnotionTest in 7.23 seconds (JVM running for 9.065)
    类名 :com.test.importdemo.TestC
    2019-01-31 14:23:15.330  INFO 1196 --- [ 
    

    3.4 通过 ImportBeanDefinitionRegistrar 方式导入的类   

    1.新建TestD.class

    public class TestD {
        public void fun(String str) {
            System.out.println(str);
        }
    
        public void printName() {
            System.out.println("类名 :" + Thread.currentThread().getStackTrace()[1].getClassName());
        }
    }
    

    2.新建SelfImportBeanDefinitionRegistrar.class,实现接口ImportBeanDefinitionRegistrar,注入TestD.class

    public class SelfImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            RootBeanDefinition root = new RootBeanDefinition(TestD.class);
            registry.registerBeanDefinition("testD", root);
        }
    }
    

    3.ImportConfig类上加上导入SelfImportBeanDefinitionRegistrar.class

    @Import({TestA.class,TestB.class,SelfImportSelector.class,
            SelfImportBeanDefinitionRegistrar.class})
    @Configuration
    public class ImportConfig {
    }
    

    4.测试结果

        @Autowired
        TestD testD;
    
    
        @Test
        public void TestD() {
            testD.printName();
        }
    

    打印:

    ImportAnnotionTest in 7.817 seconds (JVM running for 9.874)
    类名 :com.test.importdemo.TestD
    2019-01-31 14:30:05.781  INFO 23476 --- [ 
    

    通过以上几种方法都是能成功注入Spring.

    4. 详细过程解析

    这里主要看 ConfigurationClassParser.java 里面 的
    doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) 这个方法. 具体定位到 源码的302 行代码
    为啥不从头梳理,这里Spring 启动过程比较复杂,要是从头梳理,涉及的东西比较多,好多人看了就会累了,放弃了,我们就单个点熟悉 ,最后再进行汇总
    在这里插入图片描述

    4.1 getImports 方法

    在分析这个方法之前,我们先看一下 getImports 方法,这个方法就是获取所有的@import 里面的类
    这里是获取 @import 里面的类,大致流程如下:
    1. 定义一个 visited 的集合,用作 是否已经 判断过的标志
    2. 这里就是获取sourceClass 上面的 所有的 annotation,并挨个判断, 如果不是 @import ,那就 进一步递归 调用 对应的 annotation,直到全部结束
    3. 加载sourceClass 里面 的@Import annotation 里面对应的类名 ,最后返回

    	private Set<SourceClass> getImports(SourceClass sourceClass) throws IOException {
    		Set<SourceClass> imports = new LinkedHashSet<>();
    		Set<SourceClass> visited = new LinkedHashSet<>();
    		collectImports(sourceClass, imports, visited);
    		return imports;
    	}
    	// 这里就是获取sourceClass 上面的 所有的 annotation, 如果不是 @import ,那就 进一步递归 调用 对应的 annotation,直到全部结束
    	private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited)
    			throws IOException {
    
    		if (visited.add(sourceClass)) {
    			for (SourceClass annotation : sourceClass.getAnnotations()) {
    				String annName = annotation.getMetadata().getClassName();
    				if (!annName.equals(Import.class.getName())) {
    					collectImports(annotation, imports, visited);
    				}
    			}
    			imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));
    		}
    	}
    
    

    4.2 processImports 方法

    processImports 这个方法 的代码逻辑也很清晰,流程图如下:

    在这里插入图片描述

    大致的流程如下:

    1. 判断 importCandidates 是否为空,为空 退出

    2. 判断isChainedImportOnStack ,如果为true ,加入 problemReporter 里面的error ,并退出

    3. 把当前的 configClass 加入到 ImportStack里面,ImportStack 是继承了 ArrayDeque // TODO 和实现了 ImportRegistry// TODO

    4. 对 getImports 里面获取到的 需要import 的类 进行遍历 处理

      4.1 如果是 ImportSelector 类型,首先实例一个 ImportSelector 对象,然后 对其进行 Aware 扩展(如果 实现了 Aware 接口)

      4.1.2 进一步判断 是否 是 DeferredImportSelector 类型,如果是 ,加入到 deferredImportSelectors 里面,最后处理 ,这里可以看一下 方法parse(Set configCandidates), 里面最后一行才调用,这也就是 有的时候,如果想最后注入,就可以定义为deferredImportSelectors 类型

      4.1.2 如果 不是 DeferredImportSelector 类型 ,那就 调用 selectImports 方法,获取到所有的需要 注入的类,这时 再次调用 processImports 方法,这里调用processImports 方法,其实 是把 这些需要注入的类当成普通的 @Configuration 处理

    5. 如果是 ImportBeanDefinitionRegistrar 类型,这里也是 先实例一个对象,然后加入到 importBeanDefinitionRegistrars 里面,后续 会在 ConfigurationClassBeanDefinitionReader 这个类里面 的 loadBeanDefinitionsFromRegistrars 方法处理的

    6.如果上面两种类型都不是,那就是当初普通的 带有@Configuration 的类进行处理了

    在这里插入图片描述

    展开全文
  • Spring @Import注解 —— 导入资源

    万次阅读 多人点赞 2018-08-02 12:19:17
    在应用中,有时没有把某个类注入到IOC容器中,但在运用的时候需要获取该类对应的bean,此时就需要用到@Import注解。示例如下:  先创建两个类,不用注解注入到IOC容器中,在应用的时候在导入到当前容器中。  1、...

    在应用中,有时没有把某个类注入到IOC容器中,但在运用的时候需要获取该类对应的bean,此时就需要用到@Import注解。示例如下: 
    先创建两个类,不用注解注入到IOC容器中,在应用的时候在导入到当前容器中。 
    1、创建Dog和Cat类 
    Dog类:

    package com.example.demo;
    
    public class Dog {
    
    }

    Cat类:

    package com.example.demo;
    
    public class Cat {
    
    }

    2、在启动类中需要获取Dog和Cat对应的bean,需要用注解@Import注解把Dog和Cat的bean注入到当前容器中。

    package com.example.demo;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Import;
    
    //@SpringBootApplication
    @ComponentScan
    /*把用到的资源导入到当前容器中*/
    @Import({Dog.class, Cat.class})
    public class App {
    
        public static void main(String[] args) throws Exception {
    
            ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
            System.out.println(context.getBean(Dog.class));
            System.out.println(context.getBean(Cat.class));
            context.close();
        }
    }

    3、运行该启动类,输出结果:

    com.example.demo.Dog@4802796d
    com.example.demo.Cat@34123d65

    从输出结果知,@Import注解把用到的bean导入到了当前容器中。

    另外,也可以导入一个配置类 
    还是上面的Dog和Cat类,现在在一个配置类中进行配置bean,然后在需要的时候,只需要导入这个配置就可以了,最后输出结果相同。

    MyConfig 配置类:

    package com.example.demo;
    import org.springframework.context.annotation.Bean;
    
    public class MyConfig {
    
        @Bean
        public Dog getDog(){
            return new Dog();
        }
    
        @Bean
        public Cat getCat(){
            return new Cat();
        }
    
    }

    比如若在启动类中要获取Dog和Cat的bean,如下使用:

    package com.example.demo;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Import;
    
    //@SpringBootApplication
    @ComponentScan
    /*导入配置类就可以了*/
    @Import(MyConfig.class)
    public class App {
    
        public static void main(String[] args) throws Exception {
    
            ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
            System.out.println(context.getBean(Dog.class));
            System.out.println(context.getBean(Cat.class));
            context.close();
        }
    }
    展开全文
  • link和@import的区别?

    2019-05-20 14:12:51
    XML/HTML代码 <link rel='stylesheet' rev='stylesheet' href='CSS文件' type='text/css' media='all' /> ... <style type='text/css' media='screen'>...@import url('CSS文件'); </style&...

     

    XML/HTML代码

    <link rel='stylesheet' rev='stylesheet' href='CSS文件 ' type='text/css' media='all' />

    XML/HTML代码

    <style type='text/css' media='screen'>

    @import url('CSS文件 ');

    </style>

    两者都是外部引用CSS的方式,但是存在一定的区别:

    区别1: link 是 XHTML 标签,除了加载 CSS 外,还可以定义 RSS 等其他事务; @import 属于 CSS 范畴,只能加载 CSS 。

    区别2: link 引用 CSS 时,在页面载入时同时加载; @import 需要页面网页完全载入以后加载

    区别3: link 是 XHTML 标签,无兼容问题; @import 是在 CSS2.1 提出的,低版本的浏览器不支持

    区别4: link 支持使用 Javascript 控制 DOM 去改变样式;而 @import 不支持。

    展开全文
  • 在平时看源码或者很多配置类上面都会出现@Import注解,功能就是和Spring XML 里面 的 一样. @Import注解是用来导入配置类或者一些需要前置加载的类. ​ 2.源码解析 2.1 导入配置的三种类型 @Import支持 三种方式 1.带...
  • @Import

    2019-07-16 05:32:04
    @Import的源码 package org.springframework.context.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import ja...
  • @import

    2019-07-27 15:12:39
    源引:https://stackoverflow.com/questions/18947516/import-vs-import-ios-7/18947634# @import vs #import - iOS 7 转载于:https://www.cnblogs.com/gaozhang12345/p/5995890.html
  • Vue中的import中@的作用

    万次阅读 2018-08-01 10:53:17
    这是webpack的路径别名,相关代码定义在配置文件webpack.base.config里: resolve: { // 自动补全的扩展名 extensions: ['.js', '... // 例如 import Vue from 'vue',会自动到 'vue/dist/vue.common.js'中寻找 ...
  • @import 后面的波浪号~ 代表什么意思

    千次阅读 2019-02-20 21:17:59
    @import "~bootstrap/dist/css/bootstrap.min.css"; @import "~font-awesome/css/font-awesome.min.css"; 前面加 ~ 表示你后面的值为 alias, 然后就会去 webpack alias 配置中找相应的值, 然后...
  • Spring中@Import注解的作用和使用

    万次阅读 2018-09-28 14:05:11
    @Import用来导入@Configuration注解的配置类、声明@Bean注解的bean方法、导入ImportSelector的实现类或导入ImportBeanDefinitionRegistrar的实现类。 @Import注解的作用 查看Import注解源码 /** * Indicates one ...
  • @import ~ 是什么意思

    千次阅读 2020-03-08 17:48:03
    https://blog.csdn.net/qq_27970999/article/details/87823705?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task...@import "~bootstrap/dist/css/bootstrap....
  • unused import statement解决方法

    万次阅读 多人点赞 2016-10-12 18:57:06
    file下有invalidate caches/restart选项,点击即可
  • 以上只是提醒你导入了但没有使用,不是报错,原因好像是因为开了PEP8自动检查 TKS!
  • Python中from...importimport......as的区别

    万次阅读 多人点赞 2016-08-26 13:53:44
    from...import 如 from A import b,相当于 import A b=A.b 再如: "from t2 import var1" 相当于: import t2 var1= t2.var1 在此过程中有一个隐含的赋值的过程 import......as import A as B,给予A库一...
  • Unused import statement解决方法

    万次阅读 热门讨论 2018-08-20 08:08:54
    前言:  一直都能运行的项目,不知道怎么回事就突然报了这个问题   问题截图:   问题原因:  maven导入的项目的pom文件出了问题   问题解决:  在IDEA中找到pom文件右击-...虽然是自己粗心而为...
  • IDEA 修改Import 不是improt* 为单独import

    万次阅读 2014-10-17 09:51:38
    IDEA 修改Import 不是improt* 为单独import
  • Python中import, from...import,import...as的区别

    万次阅读 多人点赞 2017-07-26 10:04:47
    在python中import或者from…import是用来导入相应的模块。举个例子:import datetime print(datetime.datetime.now())以上代码实现输出系统当前时间,是引入整个datetime包,然后再调用datetime这个类中的now()方法...
  • from __future__ import absolute_import的作用

    万次阅读 多人点赞 2016-04-03 16:20:56
    关于这句from __future__ import absolute_import的作用: 直观地看就是说”加入绝对引入这个新特性”。说到绝对引入,当然就会想到相对引入。那么什么是相对引入呢?比如说,你的包结构是这样的: pkg/ pkg/init.py...
  • golang中("import cycle not allowed")错误

    万次阅读 2016-12-30 15:44:08
    golang不允许循环导包,如果检测到import cycle,会在编译时报错,通常import cycle是因为设计错误或包的规划问题。 import( "package A" "package B" ) 如果package A中已经导入package B,而本package中...
  • import numpy 和 from numpy import*的区别

    万次阅读 2017-10-22 21:06:51
    import numpy,如果使用numpy的属性都需要在前面加上numpy from numpy import *,则不需要加入numpy 后者不建议使用,如果下次引用和numpy里的函数一样的情况,就会出现命名冲突。
1 2 3 4 5 ... 20
收藏数 3,846,491
精华内容 1,538,596
关键字:

@import