java免费批注组件_spring基本组件及注解

9508f4ccfd57323cfe4baf80d1d9b264.png

spring基本组件如上图:

spring配置文件

最初使用xml配置文件,然后转向注解。

//配置类====配置文件

@Configuration

public class MainConfig {

//给容器中注册一个bean, 类型为返回值的类型,

//注意以@Bean注册bean,Id默认为方法名,也可通过@Bean注解的值来修改

@Bean

public Person person01(){

return new Person("username",20);

}

}

public class MainTest2 {

public static void main(String args[]){

//加载注解的配置文件

ApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);

//从容器中获取bean

//Person person = (Person) app.getBean("person01");

//System.out.println(person);

String[] namesForBean = app.getBeanNamesForType(Person.class);

for(String name:namesForBean){

System.out.println(name);

}

}

}

@ComponentScan扫描规则

@Configuration

@ComponentScan(value="com.enjoy.cap2", includeFilters={

@Filter(type=FilterType.ANNOTATION, classes={Controller.class})

}, useDefaultFilters=false)

public class Cap2MainConfig {

//给容器中注册一个bean, 类型为返回值的类型,

@Bean

public Person person01(){

return new Person("james",20);

}

}

value的值说明是扫描此包下面的所有类

includeFilters表示使用自定义的过滤器,此时useDefaultFilters应该为false屏蔽默认过滤器,自定义的才生效(demo中表示只扫描Controller类型的类)

另外的excludeFilters就是在默认过滤器下再过滤指定的类,自定义过滤器即可,implements

TypeFilter即可自定义

@ComponentScan value:指定要扫描的包

excludeFilters = Filter[] 指定扫描的时候按照什么规则排除那些组件

includeFilters = Filter[] 指定扫描的时候只需要包含哪些组件

useDefaultFilters = false 默认是true,扫描所有组件,要改成false

----扫描规则如下

FilterType.ANNOTATION:按照注解

FilterType.ASSIGNABLE_TYPE:按照给定的类型;比如按BookService类型

FilterType.ASPECTJ:使用ASPECTJ表达式

FilterType.REGEX:使用正则指定

FilterType.CUSTOM:使用自定义规则,自已写类,实现TypeFilter接口

//FilterType.CUSTOM的例子,常用

先新增自定义过滤规则类: TestTypeFilter

@ComponentScan(value="com.enjoy.cap2",includeFilters={

@Filter(type=FilterType.CUSTOM,classes={TestTypeFilter.class})

},useDefaultFilters=false)

public class TestTypeFilter implements TypeFilter{

private ClassMetadata classMetadata;

/*

* MetadataReader:读取到当前正在扫描类的信息

* MetadataReaderFactory:可以获取到其他任何类信息

*/

@Override

public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)

throws IOException {

//获取当前类注解的信息

AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();

//获取当前正在扫描的类信息

classMetadata = metadataReader.getClassMetadata();

//获取当前类资源(类的路径)

Resource resource = metadataReader.getResource();

String className = classMetadata.getClassName();

System.out.println("----->"+className);

if(className.contains("er")){//当类包含er字符, 则匹配成功,返回true

return true;

}

return false;

}

}

@scope注解

spring中bean默认是单例singleton,@Scope(“prototype”)为多实例。

//多实例

@Scope("prototype")

@Bean

public Person person(){

return new Person("username",20);

}

prototype: 多实例:IOC容器启动并不会去调用方法创建对象放在容器中,而是

每次获取的时候才会调用方法创建对象

singleton: 单实例(默认):IOC容器启动会调用方法创建对象放到IOC容器中

以后每交获取就是直接从容器(理解成从map.get对象)中拿

request: 主要针对WEB应用,同一次请求创建一个实例

session: 同一个session创建一个实例(主要掌握前面2个即可,后面2个了解)

lazy懒加载

@lazy当加入此注解时,则getBean调用的时候才会把实例加载到IOC容器。

@Conditional条件注册bean

public class WinCondition implements Condition{

/*

*ConditionContext: 判断条件可以使用的上下文(环境)

*AnnotatedTypeMetadata: 注解的信息

*

*/

@Override

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

// TODO 是否为WINDOW系统

//能获取到IOC容器正在使用的beanFactory

ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();

//获取当前环境变量(包括我们操作系统是WIN还是LINUX??)

Environment environment = context.getEnvironment();

String os_name = environment.getProperty("os.name");

if(os_name.contains("Windows")){

return true;

}

return false;

}

}

//加入条件注解则会按自定义的逻辑注册,true时注册到容器

@Conditional(WinCondition.class)

@Bean("lison")

public Person lison(){

System.out.println("给容器中添加lison.......");

return new Person("Lison",28);

}

@Import注册bean

@Import(value = { Dog.class,Cat.class,JamesImportSelector.class,JamesImportBeanDefinitionRegistrar.class })

public class JamesImportSelector implements ImportSelector{

@Override

public String[] selectImports(AnnotationMetadata importingClassMetadata){

//返回全类名的bean

return new String[]{"com.enjoy.cap6.bean.Fish","com.enjoy.cap6.bean.Tiger"};

}

}

public class JamesImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

/*

*AnnotationMetadata:当前类的注解信息

*BeanDefinitionRegistry:BeanDefinition注册类

* 把所有需要添加到容器中的bean加入;

* @Scope

*/

@Override

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

boolean bean1 = registry.containsBeanDefinition("com.enjoy.cap6.bean.Dog");

boolean bean2 = registry.containsBeanDefinition("com.enjoy.cap6.bean.Cat");

//如果Dog和Cat同时存在于我们IOC容器中,那么创建Pig类, 加入到容器

//对于我们要注册的bean, 给bean进行封装,

if(bean1 && bean2){

RootBeanDefinition beanDefinition = new RootBeanDefinition(Pig.class);

registry.registerBeanDefinition("pig", beanDefinition);

}

}

}

给容器中注册组件的方式:

1,@Bean: [导入第三方的类或包的组件],比如Person为第三方的类, 需要在我们的IOC容器中使用

2,包扫描+组件的标注注解(@ComponentScan: @Controller, @Service @Reponsitory @

Componet),一般是针对 我们自己写的类,使用这个

3,@Import:[快速给容器导入一个组件] 注意:@Bean有点简单

a,@Import(要导入到容器中的组件):容器会自动注册这个组件,bean 的 id为全类名

b,ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组

c,ImportBeanDefinitionRegistrar:可以手动添加组件到IOC容器, 所有Bean的注册可以使用BeanDifinitionRegistry,写JamesImportBeanDefinitionRegistrar实现ImportBeanDefinitionRegistrar接口即可

4,使用Spring提供的FactoryBean(工厂bean)进行注册,实现FactoryBean接口即可,在实现方法getObject里可写注册的实例。注意:如MyFactoryBean为实现了FactoryBean接口,getBean("myFactoryBean")获取的实例为实现的getObject方法里的实例,getBean("&myFactoryBean")则为MyFactoryBean实例,具体逻辑查看源码可发现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值