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注解-组件注册

spring注解之组件注册

spring 注解驱动开发组件注册

Spring应用于组件注册的注解

Spring注解驱动开发-----组件注册

如何将一个组件注册到容器中?Bean注解一招解决-