Spring注解驱动:组件注册(一)
文章目录
- 1.Spring简单环境
- 2.Spring注解容器
- 2.1 代码示例
- 2.2 给容器注册组件4种方式
- 2.2.1 工厂创建对象
- 2.3 声明周期
- 2.3.1 Bean指定初始化和销毁方法
- 2.3.2 Bean实现InitializingBean
- 2.3.3 使用JSR250
- 2.3.4 BeanPostProcessor
- 2.4 属性赋值
- 2.4.1 @Value
- 2.4.2 自动装配 @Autowired
- 3.Spring常用注解驱动
- 3.1 @Configuration
- 3.2 @Bean
- 3.3 @ComponentScan与@ComponentScans
- 3.3.1 简单扫描
- 3.3.2 过滤扫描
- 3.4 @Scope
- 3.5 @Lazy
- 3.6 @Conditional
- 3.7 @Import
- 3.7.1 直接导入类
- 3.7.2 ImportSelector
- 3.7.3 ImportBeanDefinitionRegistrar
- 3.8 @Value与@PropertySource
- 3.9 @Autowired
- 3.10 @Qualifier
- 3.11 @Primary
- 3.12 @Resource
- 3.13 @Inject
- 3.14 @Profile
本文是根据尚硅谷老师讲解整理,供后续学习查阅使用。
1.Spring简单环境
1.建立一个Spring简单项目
2.相关配置与代码
<!--添加spring基本依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.3.12.RELEASE</version></dependency>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"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"><bean id="person" class="com.zy.bean.Person"><property name="pName" value="张三"></property><property name="pAge" value="18"></property></bean></beans>
public class Person {private String pName;private Integer pAge;
public class MainTest {public static void main(String[] args) {ClassPathXmlApplicationContext xmlApplicationContext = new ClassPathXmlApplicationContext("bean.xml");Object person = (Person)xmlApplicationContext.getBean("person");System.out.println(person);}}
2.Spring注解容器
2.1 代码示例
即增加一个配置类,利用注解容器进行获取即可
//配置类==配置文件(bean.xml)
@Configuration //告诉Spring这是一个配置类
public class BeanConfig {//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id@Bean("person")public Person person(){return new Person("lisi", 20);}}
public class MainTestConfig {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);Person bean = applicationContext.getBean(Person.class);System.out.println(bean);}}
2.2 给容器注册组件4种方式
- 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
- 2)、@Bean[导入的第三方包里面的组件,即没有添加@Controller等注解的类]
- 3)、@Import[快速给容器中导入一个组件]
1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
2)、ImportSelector:返回需要导入的组件的全类名数组;
3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中 - 4)、使用Spring提供的 FactoryBean(工厂Bean);
1)、默认获取到的是工厂bean调用getObject创建的对象
2)、要获取工厂Bean本身,我们需要给id前面加一个&
&ToolFactoryBean
2.2.1 工厂创建对象
//创建一个Spring定义的FactoryBean
public class ToolFactoryBean implements FactoryBean<Tool> {//返回一个Color对象,这个对象会添加到容器中@Overridepublic Tool getObject() throws Exception {// TODO Auto-generated method stubSystem.out.println("ToolFactoryBean...getObject...");return new Tool();}@Overridepublic Class<?> getObjectType() {// TODO Auto-generated method stubreturn Tool.class;}//是单例?//true:这个bean是单实例,在容器中保存一份//false:多实例,每次获取都会创建一个新的bean;@Overridepublic boolean isSingleton() {// TODO Auto-generated method stubreturn true;}}
public class Tool {}
@Configuration
public class BeanConfig {@Beanpublic ToolFactoryBean toolFactoryBean(){return new ToolFactoryBean();}
}
private void printBeans(AnnotationConfigApplicationContext applicationContext){String[] definitionNames = applicationContext.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);}}@Testpublic void testFactory(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);printBeans(applicationContext);Object bean = applicationContext.getBean("toolFactoryBean");System.out.println("bean = " + bean.getClass());Object bean2 = applicationContext.getBean("&toolFactoryBean");System.out.println("bean2 = " + bean2.getClass());}
2.3 声明周期
/*** bean的生命周期:* bean创建---初始化----销毁的过程* 容器管理bean的生命周期;* 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法* * 构造(对象创建)* 单实例:在容器启动的时候创建对象* 多实例:在每次获取的时候创建对象\* * BeanPostProcessor.postProcessBeforeInitialization* 初始化:* 对象创建完成,并赋值好,调用初始化方法。。。* BeanPostProcessor.postProcessAfterInitialization* 销毁:* 单实例:容器关闭的时候* 多实例:容器不会管理这个bean;容器不会调用销毁方法;* * * 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,* 一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization* * BeanPostProcessor原理* populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值* initializeBean* {* applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);* invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化* applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);*}* * * * 1)、指定初始化和销毁方法;* 通过@Bean指定init-method和destroy-method;* 2)、通过让Bean实现InitializingBean(定义初始化逻辑),* DisposableBean(定义销毁逻辑);* 3)、可以使用JSR250;* @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法* @PreDestroy:在容器销毁bean之前通知我们进行清理工作* 4)、BeanPostProcessor【interface】:bean的后置处理器;* 在bean初始化前后进行一些处理工作;* postProcessBeforeInitialization:在初始化之前工作* postProcessAfterInitialization:在初始化之后工作* * Spring底层对 BeanPostProcessor 的使用;* bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxx BeanPostProcessor;* * @author lfy**/
2.3.1 Bean指定初始化和销毁方法
public class Color {public Color() {System.out.println("Color 构造方法执行");}public void init(){System.out.println("Color init方法执行");}public void detory(){System.out.println("Color detory方法执行");}}
@Configuration
public class BeanConfig {@Bean(initMethod="init",destroyMethod="detory")public Color color(){return new Color();}
}
@Testpublic void testLive(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);printBeans(applicationContext);applicationContext.close();}
2.3.2 Bean实现InitializingBean
@Component
public class Color implements InitializingBean, DisposableBean {public Color() {System.out.println("Color 构造方法执行");}@Overridepublic void destroy() throws Exception {System.out.println("Color detory方法执行");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("Color afterPropertiesSet方法执行,属性值赋值完就调用这个方法");}
}
@Configuration
@ComponentScan("com.zy")
public class BeanConfig {}
@Testpublic void testLive(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);printBeans(applicationContext);applicationContext.close();}
2.3.3 使用JSR250
@PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
@PreDestroy:在容器销毁bean之前通知我们进行清理工作
@Component
public class Color{public Color() {System.out.println("Color 构造方法执行");}//对象创建并赋值之后@PostConstructpublic void init(){System.out.println("Color PostConstruct方法执行");}@PreDestroypublic void destroy(){System.out.println("Color PreDestroy方法执行");}
}
@Configuration
@ComponentScan("com.zy")
public class BeanConfig {}
@Testpublic void testLive(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);printBeans(applicationContext);applicationContext.close();}
2.3.4 BeanPostProcessor
在bean初始化前后进行一些处理工作:
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之后工作
@Component
public class Color{public Color() {System.out.println("Color 构造方法执行");}//对象创建并赋值之后@PostConstructpublic void init(){System.out.println("Color init方法执行");}@PreDestroypublic void destroy(){System.out.println("Color destroy方法执行");}
}
/*** 后置处理器:初始化前后进行处理工作* 将后置处理器加入到容器中*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// TODO Auto-generated method stubSystem.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// TODO Auto-generated method stubSystem.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);return bean;}}
@Configuration
@ComponentScan("com.zy")
public class BeanConfig {}
@Testpublic void testLive(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);printBeans(applicationContext);applicationContext.close();}
2.4 属性赋值
/*** 自动装配;* Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值;* * 1)、@Autowired:自动注入:* 1)、默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值* 2)、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找* applicationContext.getBean("bookDao")* 3)、@Qualifier("bookDao"):使用@Qualifier指定需要装配的组件的id,而不是使用属性名* 4)、自动装配默认一定要将属性赋值好,没有就会报错;* 可以使用@Autowired(required=false);* 5)、@Primary:让Spring进行自动装配的时候,默认使用首选的bean;* 也可以继续使用@Qualifier指定需要装配的bean的名字* BookService{* @Autowired* BookDao bookDao;* }* * 2)、Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[java规范的注解]* @Resource:* 可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;* 没有能支持@Primary功能没有支持@Autowired(reqiured=false);* @Inject:* 需要导入javax.inject的包,和Autowired的功能一样。没有required=false的功能;* @Autowired:Spring定义的; @Resource、@Inject都是java规范* * AutowiredAnnotationBeanPostProcessor:解析完成自动装配功能; * * 3)、 @Autowired:构造器,参数,方法,属性;都是从容器中获取参数组件的值* 1)、[标注在方法位置]:@Bean+方法参数;参数从容器中获取;默认不写@Autowired效果是一样的;都能自动装配* 2)、[标在构造器上]:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取* 3)、放在参数位置:* * 4)、自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx);* 自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware;* 把Spring底层一些组件注入到自定义的Bean中;* xxxAware:功能使用xxxProcessor;* ApplicationContextAware==》ApplicationContextAwareProcessor;* * **/
2.4.1 @Value
参考常见3常用驱动
2.4.2 自动装配 @Autowired
参考常见3常用驱动
3.Spring常用注解驱动
3.1 @Configuration
配置类等同之前的applicationContext.xml配置文件,即告诉spring这个一个配置类
//配置类==配置文件(bean.xml)
@Configuration //告诉Spring这是一个配置类
public class BeanConfig {
3.2 @Bean
- 使用注解在容器中注册bean,默认id是方法名,返回值为bean的类型
- @Bean的vale值可以指定生成bean的id
//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id@Bean("person1")public Person person2(){return new Person("lisi", 20);}
作用类似如下:
<bean id="person" class="com.zy.bean.Person"><property name="pName" value="张三"></property><property name="pAge" value="18"></property></bean>
3.3 @ComponentScan与@ComponentScans
以后我们使用注解的场景比较多,而使用xml配置的场景会越来越少,那么我们可以使用@ComponentScan来扫描我们标注的一些类,把这些类根据条件加载到Spring容器中
3.3.1 简单扫描
1.简单扫描
2.相关代码
@Configuration //告诉Spring这是一个配置类
@ComponentScan(value = "com.zy")
public class BeanConfig {//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id@Bean("person1")public Person person(){return new Person("lisi", 20);}}@Controller
public class PersonController {}@Service
public class PersonService {}//名字默认是类名首字母小写
@Repository
public class PersonDao {}
@Testpublic void testScan(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);//获取 Spring 容器中定义的所有 JavaBean 的名称String[] definitionNames = applicationContext.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);}}
功能等同于:
包扫描、只要标注了@Controller、@Service、@Repository,@Component<context:component-scan base-package="com.zy"></context:component-scan>
3.3.2 过滤扫描
@ComponentScan value:指定要扫描的包
- excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
- includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
FilterType.ANNOTATION:按照注解
FilterType.ASSIGNABLE_TYPE:按照给定的类型;
FilterType.ASPECTJ:使用ASPECTJ表达式
FilterType.REGEX:使用正则指定
FilterType.CUSTOM:使用自定义规则,这个需要增加一个规则类,后续用到再查看
例如下面,去掉默认扫描配置,只扫描规定的相关类
//配置类==配置文件(bean.xml)
@Configuration //告诉Spring这是一个配置类
@ComponentScans(value = {@ComponentScan(value="com.zy",includeFilters = {@ComponentScan.Filter(type=FilterType.ANNOTATION,classes={Controller.class}),@ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE,classes={PersonService.class})},useDefaultFilters = false)}
)
public class BeanConfig {//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id@Bean("person1")public Person person(){return new Person("lisi", 20);}}
3.4 @Scope
//默认是单实例的/*** @Scope:调整作用域* prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。* 每次获取的时候才会调用方法创建对象;* singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。* 以后每次获取就是直接从容器(map.get())中拿,* request:同一次请求创建一个实例* session:同一个session创建一个实例**/@Scope("prototype")@Bean("person")public Person person(){System.out.println("给容器中添加Person....");return new Person("张三", 25);}
3.5 @Lazy
//默认是单实例的/*** 懒加载:* 单实例bean:默认在容器启动的时候创建对象;* 懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;**/@Lazy@Bean("person")public Person person(){System.out.println("给容器中添加Person....");return new Person("张三", 25);}
3.6 @Conditional
按照一定的条件进行判断,满足条件给容器中注册bean
举例,根据不同系统加载不同的bean到Spring容器中
//判断是否windows系统
public class WindowsCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {Environment environment = context.getEnvironment();String property = environment.getProperty("os.name");if(property.contains("Windows")){return true;}return false;}}
//判断是否linux系统
public class LinuxCondition implements Condition {/*** ConditionContext:判断条件能使用的上下文(环境)* AnnotatedTypeMetadata:注释信息*/@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// TODO是否linux系统//1、能获取到ioc使用的beanfactoryConfigurableListableBeanFactory 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注册情况,也可以给容器中注册beanboolean definition = registry.containsBeanDefinition("person");if(property.contains("linux")){return true;}return false;}}
@Configuration //告诉Spring这是一个配置类
public class BeanConfig {@Conditional(WindowsCondition.class)@Bean("WindowsBean")public Person person01(){return new Person("windows",62);}@Conditional(LinuxCondition.class)@Bean("linusBean")public Person person02(){return new Person("linus", 48);}}
@Testpublic void testCond(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);String[] namesForType = applicationContext.getBeanNamesForType(Person.class);ConfigurableEnvironment environment = applicationContext.getEnvironment();//动态获取环境变量的值;Windows 10String property = environment.getProperty("os.name");System.out.println(property);for (String name : namesForType) {System.out.println(name);}}
设置环境变量
3.7 @Import
3.7.1 直接导入类
@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
public class Red {}
@Configuration
@Import(Red.class)
public class BeanConfig {}
@Testpublic void testImport(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);printBeans(applicationContext);Red bean = applicationContext.getBean(Red.class);System.out.println(bean);}private void printBeans(AnnotationConfigApplicationContext applicationContext){String[] definitionNames = applicationContext.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);}}
3.7.2 ImportSelector
ImportSelector:返回需要导入的组件的全类名数组;
public class Yellow {}public class Blue {}public class Red {}
//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {//返回值,就是到导入到容器中的组件全类名//AnnotationMetadata:当前标注@Import注解的类的所有注解信息@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {// TODO Auto-generated method stub//importingClassMetadata//方法不要返回null值return new String[]{"com.zy.bean.Blue","com.zy.bean.Yellow"};}}
@Testpublic void testImport(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);printBeans(applicationContext);Blue bean = applicationContext.getBean(Blue.class);System.out.println(bean);}private void printBeans(AnnotationConfigApplicationContext applicationContext){String[] definitionNames = applicationContext.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);}}
3.7.3 ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar:手动注册bean到容器中
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {/*** AnnotationMetadata:当前类的注解信息* BeanDefinitionRegistry:BeanDefinition注册类;* 把所有需要添加到容器中的bean;调用* BeanDefinitionRegistry.registerBeanDefinition手工注册进来*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {boolean definition = registry.containsBeanDefinition("com.zy.bean.Red");boolean definition2 = registry.containsBeanDefinition("com.zy.bean.Blue");if(definition && definition2){//指定Bean定义信息;(Bean的类型,Bean。。。)RootBeanDefinition beanDefinition = new RootBeanDefinition(Color.class);//注册一个Bean,指定bean名registry.registerBeanDefinition("Color", beanDefinition);}}}
@Configuration
@Import({Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class BeanConfig {}
@Testpublic void testImport(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);printBeans(applicationContext);Blue bean = applicationContext.getBean(Blue.class);System.out.println(bean);}private void printBeans(AnnotationConfigApplicationContext applicationContext){String[] definitionNames = applicationContext.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);}}
3.8 @Value与@PropertySource
使用@Value赋值;
1、基本数值
2、可以写SpEL; #{}
3、可以写${};取出配置文件【properties】中的值(在运行环境变量里面的值)
person.properties
person.nickName=\u5C0F\u674E\u56DB
public class Person {@Value("${person.nickName}")private String pName;@Value("#{20-2}")private Integer pAge;
//使用@PropertySource读取外部配置文件中的k/v保存到运行的环境变量中;加载完外部的配置文件以后使用${}取出配置文件的值
@PropertySource(value={"classpath:/person.properties"})
@Configuration
public class BeanConfig {@Beanpublic Person person(){return new Person();}}
@Testpublic void testAttr(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);Person bean = applicationContext.getBean(Person.class);System.out.println("bean = " + bean);ConfigurableEnvironment environment = applicationContext.getEnvironment();String property = environment.getProperty("person.nickName");System.out.println(property);}
3.9 @Autowired
@Service
public class PersonService {public void show(){System.out.println("PersonService show执行..");}
}
@Controller
public class PersonController {@Autowiredprivate PersonService personService;public void exc(){System.out.println("PersonController : personService = " + personService);personService.show();}}
@Configuration
@ComponentScan("com.zy")
public class BeanConfig {}
@Testpublic void testAuto(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);PersonController personController = (PersonController)applicationContext.getBean("personController");personController.exc();PersonService personService = (PersonService)applicationContext.getBean("personService");System.out.println("personService = " + personService);}
自动装配的变量名,默认就是类首字母小写的名字,我们也可以指定
@Configuration
@ComponentScan("com.zy")
public class BeanConfig {@Bean("personService2")public PersonService personService(){PersonService personService = new PersonService();personService.setTag("2");return personService;}}
@Controller
public class PersonController {@Autowiredprivate PersonService personService2;public void exc(){System.out.println("PersonController : personService = " + personService2);personService2.show();}}@Service
public class PersonService {private String tag;public String getTag() {return tag;}public void setTag(String tag) {this.tag = tag;}public void show(){System.out.println("PersonService show执行.."+tag);}
}
@Testpublic void testAuto(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);PersonController personController = (PersonController)applicationContext.getBean("personController");personController.exc();PersonService personService2 = (PersonService)applicationContext.getBean("personService2");System.out.println("personService = " + personService2 );personService2.show();}
3.10 @Qualifier
指定需要自动装配的对象,比如上面例子,容器里有personService ,personService2两个实例对象,通过这个注解,就指定容器中personService对象注入到变量personService2中
@Controller
public class PersonController {@Qualifier("personService")@Autowiredprivate PersonService personService2;public void exc(){System.out.println("PersonController : personService = " + personService2);personService2.show();}}
3.11 @Primary
若有多个相同类型的实例,我们可以指定一个实例,当spring注入的时候,优先注入我们默认设置的这个
@Configuration
@ComponentScan("com.zy")
public class BeanConfig {@Primary@Bean("personService2")public PersonService personService(){PersonService personService = new PersonService();personService.setTag("2");return personService;}}
@Controller
public class PersonController {@Autowiredprivate PersonService personService;public void exc(){System.out.println("PersonController : personService = " + personService);personService.show();}}
@Service
public class PersonService {private String tag;public String getTag() {return tag;}public void setTag(String tag) {this.tag = tag;}public void show(){System.out.println("PersonService show执行.."+tag);}
}
@Testpublic void testAuto(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);PersonController personController = (PersonController)applicationContext.getBean("personController");personController.exc();PersonService personService2 = (PersonService)applicationContext.getBean("personService2");System.out.println("personService = " + personService2 );personService2.show();}
3.12 @Resource
这个注解是根据变量名来注入的,例子和上面一样,不过注解换成这个了
@Controller
public class PersonController {@Resource(name = "personService2")private PersonService personService;public void exc(){System.out.println("PersonController : personService = " + personService);personService.show();}}
3.13 @Inject
需要添加依赖
<dependency><groupId>javax.inject</groupId><artifactId>javax.inject</artifactId><version>1</version></dependency>
@Controller
public class PersonController {@Injectprivate PersonService personService;public void exc(){System.out.println("PersonController : personService = " + personService);personService.show();}}
3.14 @Profile
/*** Profile:* Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;* * 开发环境、测试环境、生产环境;* 数据源:(/A)(/B)(/C);* * * @Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件* * 1)、加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境* 2)、写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效* 3)、没有标注环境标识的bean在,任何环境下都是加载的;*/
@Configuration
public class BeanConfig {@Profile("test")@Bean("mysql")public MysqlEnv mysqlEnv(){return new MysqlEnv();}@Profile("dev")@Bean("oracle")public OracleEnv oracleEnv(){return new OracleEnv();}}
public class MysqlEnv {}public class OracleEnv {}
@Testpublic void testEnv(){//1、使用命令行动态参数: 在虚拟机参数位置加载 -Dspring.profiles.active=testAnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);printBeans(applicationContext);}
或者使用代码选择
@Testpublic void testEnv(){//1、使用命令行动态参数: 在虚拟机参数位置加载 -Dspring.profiles.active=testAnnotationConfigApplicationContext applicationContext =new AnnotationConfigApplicationContext();//1、创建一个applicationContext//2、设置需要激活的环境applicationContext.getEnvironment().setActiveProfiles("dev");//3、注册主配置类applicationContext.register(BeanConfig.class);//4、启动刷新容器applicationContext.refresh();printBeans(applicationContext);applicationContext.close();}
Spring注解驱动:组件注册(一)相关推荐
- Spring注解驱动之注册组件(spring的再回顾)
一. 组件注册 1. 给容器中注册组件 xml方式 创建一个实体类(构造方法等省略) public class Person {private String name;private Integer ...
- 【Spring注解驱动开发】使用@Scope注解设置组件的作用域
写在前面 Spring容器中的组件默认是单例的,在Spring启动时就会实例化并初始化这些对象,将其放到Spring容器中,之后,每次获取对象时,直接从Spring容器中获取,而不再创建对象.如果每次 ...
- 0、Spring 注解驱动开发
0.Spring注解驱动开发 0.1 简介 <Spring注解驱动开发>是一套帮助我们深入了解Spring原理机制的教程: 现今SpringBoot.SpringCloud技术非常火热,作 ...
- Spring注解驱动开发第26讲——总有人让我给他讲讲@EnableAspectJAutoProxy注解
@EnableAspectJAutoProxy注解 在配置类上添加@EnableAspectJAutoProxy注解,便能够开启注解版的AOP功能.也就是说,如果要使注解版的AOP功能起作用的话,那么 ...
- 【Spring注解驱动开发】二狗子让我给他讲讲@EnableAspectJAutoProxy注解
写在前面 最近,二狗子入职了新公司,新入职的那几天确实有点飘.不过慢慢的,他发现他身边的人各个身怀绝技啊,有Spring源码的贡献者,有Dubbo源码的贡献者,有MyBatis源码的贡献者,还有研究A ...
- SPRING注解驱动开发-雷神课程超详细笔记
SPRING注解驱动开发-雷神课程超详细笔记 时间:2021-03-21 2022-04-06更新:最近翻起一年多前写的笔记复习,还是收获颇多,很多当时无法理解的知识现在慢慢能理解了,可能是工作一年的 ...
- spring注解驱动开发-10 Servlet3.0
Spring AOP实现 前言 servlet3.0简介 ServletContainerInitializer shared libraries(共享库) / runtimes pluggabili ...
- spring注解驱动开发-8 Spring 扩展原理
Spring 扩展原理 前言 BeanFactoryPostProcessor 测试实例编写 ExtConfig MyBeanFactoryPostProcessor ExtTest 源码分析 Bea ...
- spring注解驱动开发-4 Spring 自动装配
Spring 自动装配 前言 Spring 自动装配的几种方式 1.@Autowired @Qualifier("组件id") @Primary 2.@Resource方式 3.@ ...
- spring注解驱动开发-7 Spring声明式事务
Spring 声明式事务 前言 @EnableTransactionManagement AutoProxyRegistrar InfrastructureAdvisorAutoProxyCreato ...
最新文章
- linux下如何判断oracle数据库tns是否设置正常
- AI攻破高数核心,1秒内精确求解微分方程、不定积分,性能远超Matlab
- STL sort()函数详解
- Xah Lee Web 李杀网
- 2篇CIKM详解阿里妈妈搜索广告CTR模型如何低碳瘦身
- NET问答: Find() 和 Where().FirstOrDefault() 该如何选择 ?
- 国际:如何识别真正的程序员
- C++11 新特性整理(2)
- python3.6.5安装步骤-Centos7 安装Python3.6.5
- mouseenter鼠标事件
- snagit 9.0注册码
- php curl 417,PHP Curl 417 Expectation Failed解决办法
- 自学Java day17 jvav网络编程 从jvav到架构师
- Android马甲包
- 北京大学C语言学习第6天
- 笔记本连接显示器没有声音解决方法
- 一条大蟒蛇和一条小毒蛇
- 浅谈晏殊几何学知识图谱技术
- 账户结构,推广计划,推广单元
- 手机控制云服务器文件,手机控制云服务器的app