spring注解-组件注册
Posted 鸟随二月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring注解-组件注册相关的知识,希望对你有一定的参考价值。
目录标题
组件注册
@Configuration@bean给容器注册组件
之前
// src\\main\\java\\com\\spring\\bean\\Person.java
//bean
package com.spring.bean;
public class Person
private String name;
private Integer age;
private String nickName;
public String getNickName()
return nickName;
public void setNickName(String nickName)
this.nickName = nickName;
public String getName()
return name;
public void setName(String name)
this.name = name;
public Integer getAge()
return age;
public void setAge(Integer age)
this.age = age;
public Person(String name, Integer age)
super();
this.name = name;
this.age = age;
public Person()
super();
// TODO Auto-generated constructor stub
@Override
public String toString()
return "Person [name=" + name + ", age=" + age + ", nickName=" + nickName + "]";
//
//src\\main\\resources\\beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<bean id="person" class="com.spring.bean.Person" >
<property name="age" value="18"></property>
<property name="name" value="zhangsan"></property>
</bean>
</beans>
//
//测试src\\main\\java\\com\\spring\\Main.java
package com.spring;
import com.spring.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main
public static void main(String[] args)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
Person bean = (Person) applicationContext.getBean("person");
System.out.println(bean);
将beans.xml换成配置类
package com.spring.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.spring.bean.Person;
//src\\main\\java\\com\\spring\\Main.java
//配置类==配置文件
@Configuration //告诉Spring这是一个配置类
public class MainConfig
//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
//@Bean
//指定id
@Bean("person")
public Person person()
return new Person("lisi", 20);
///
//测试
package com.spring;
import com.spring.bean.Person;
import com.spring.config.MainConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
/*获取Person的id*/
String[] namesForType = applicationContext.getBeanNamesForType(Person.class);
for (String name : namesForType)
System.out.println(name);
自动扫描组件
之前是在//src\\main\\resources\\beans.xml配置文件中加
<!-- 包扫描、只要标注了@Controller、@Service、@Repository,@Component --><!--use-default-filters="false这样才能只包含com.spring默认全部-->
<!-- <context:component-scan base-package="com.spring" use-default-filters="false"></context:component-scan> -->
现在在配置类src\\main\\java\\com\\spring\\config\\MainConfig.java中加入
@ComponentScan(value="com.spring") //value:指定要扫描的包
现在
建立三层
package com.spring.controller;
import org.springframework.stereotype.Controller;
@Controller
public class BookController
///
package com.spring.service;
import org.springframework.stereotype.Service;
@Service
public class BookService
/
package com.spring.dao;
import org.springframework.stereotype.Repository;
@Repository
public class BookDao
测试
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
String[] definitionNames = applicationContext.getBeanDefinitionNames();
for (String name : definitionNames)
System.out.println(name);
此外在src\\main\\java\\com\\spring\\config\\MainConfig.java配置类中类名前加
//@ComponentScan(value="com.spring",) //value:指定要扫描的包
@ComponentScans(
value =
@ComponentScan(value="com.spring",includeFilters =
/* @Filter(type=FilterType.ANNOTATION,classes=Controller.class),
@Filter(type=FilterType.ASSIGNABLE_TYPE,classes=BookService.class),*/
@ComponentScan.Filter(type= FilterType.CUSTOM,classes=MyTypeFilter.class)
,useDefaultFilters = false)
)
//@ComponentScans 如果是jdk8以上可以写多个ComponentScan,否则只能写在此中,以数组的形式
//@ComponentScan value:指定要扫描的包
//excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
//includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
//FilterType.ANNOTATION:按照注解
//FilterType.ASSIGNABLE_TYPE:按照给定的类型;
//FilterType.ASPECTJ:使用ASPECTJ表达式
//FilterType.REGEX:使用正则指定
//FilterType.CUSTOM:使用自定义规则
//useDefaultFilters = false去掉默认全局匹配
自定义规则
package com.spring.config;
import java.io.IOException;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
public class MyTypeFilter implements TypeFilter
/**
* metadataReader:读取到的当前正在扫描的类的信息
* metadataReaderFactory:可以获取到其他任何类信息的
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException
// TODO Auto-generated method stub
//获取当前类注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前类资源(类的路径)
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
System.out.println("--->"+className);
if(className.contains("er"))
return true;
return false;
设置组件作用域@Scope
之前src\\main\\resources\\beans.xml
现在
添加一个新的配置类
package com.spring.config;
import com.spring.bean.Person;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
@Configuration
public class MainConfig2
//默认是单实例的
/**
* ConfigurableBeanFactory#SCOPE_PROTOTYPE
* @see ConfigurableBeanFactory#SCOPE_SINGLETON
* @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request
* @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION sesssion
* @return\\
* @Scope:调整作用域
* prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。
* 每次获取的时候才会调用方法创建对象;
* singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。
* 以后每次获取就是直接从容器(map.get())中拿,
* request:同一次请求创建一个实例
* session:同一个session创建一个实例
*
* 懒加载:
* 单实例bean:默认在容器启动的时候创建对象;
* 懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
*
*/
@Scope("prototype")
@Bean("person")
public Person person()
System.out.println("给容器中添加Person....");
return new Person("张三", 25);
测试
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
System.out.println("ioc容器创建完成....");
Object bean = applicationContext.getBean("person");
Object bean2 = applicationContext.getBean("person");
System.out.println(bean == bean2);
懒加载@Lazy
第一次获取实例时加载
按照条件注册bean@Conditional
src\\main\\java\\com\\spring\\config\\MainConfig2.java添加
@Bean("bill")
@Conditional(WindowsCondition.class)
public Person person01()
return new Person("Bill Gates",62);
@Conditional(LinuxCondition.class)
@Bean("linus")
public Person person02()
return new Person("linus", 48);
package com.spring.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
//判断是否windows系统
public class WindowsCondition implements Condition
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("Windows"))
return true;
return false;
///
package com.spring.condition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
//判断是否linux系统
public class LinuxCondition implements Condition
/**
* ConditionContext:判断条件能使用的上下文(环境)
* AnnotatedTypeMetadata:注释信息
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)
// TODO是否linux系统
//1、能获取到ioc使用的beanfactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//2、获取类加载器
ClassLoader classLoader = context.getClassLoader();
//3、获取当前环境信息
Environment environment = context.getEnvironment();
//4、获取到bean定义的注册类
BeanDefinitionRegistry registry = context.getRegistry();
String property = environment.getProperty("os.name");
//可以判断容器中的bean注册情况,也可以给容器中注册bean
boolean definition = registry.containsBeanDefinition("person");
if(property.contains("linux"))
return true;
return false;
测试
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] namesForType = applicationContext.getBeanNamesForType(Person.class);
for (String name : namesForType)
System.out.println(name);
Mapspring注解-组件注册