Overall introduction to Spring framework functions
Spring Core Container
Core and Beans modules are the basic parts of the framework, providing IoC and dependency injection features
The core of ioc's idea is that resources are not managed by both parties who use resources, but by a third party who does not use resources, which can bring many benefits. First, centralized management of resources to realize the configurable and easy management of resources. Second, it reduces the dependence of both parties using resources, that is, the degree of coupling.
- Core mainly contains the basic core tool classes of the Spring framework. Other components of Spring need to use the classes in this package.
- Beans contains all classes related to accessing configuration files, creating and managing bean s, and performing (IoC/DI) operations
- Context modeling is based on Core and Beans modules and provides a framework object access method similar to JNDI registrar. The context module inherits the characteristics of Beans, provides a large number of extensions for the Spring Core, and adds support for internationalization (such as resource binding), event propagation, resource loading and transparent creation of context. The context module also supports some J2EE features. The ApplicationContext interface is the key to the context module
- The Expression Language module provides a powerful Expression Language for querying and manipulating objects at run time. It is an extension of the unifed expression language defined in the JSP 2.1 specification. The language supports setting / obtaining the value of attributes, attribute allocation, method call, accessing the context of arrays, containers and indexers, logical and arithmetic operators, named variables, and retrieving objects by name from the IoC container of Spring. It also supports list projection, selection, and general list aggregation
Spring container inheritance diagram
Spring IOC container bottom annotation usage
1. Form of XML configuration file
<?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.yemuxia.ioc02.Person"> <property name="id" value="1"/> <property name="name" value="Zhang San"/> </bean> </beans>
package com.yemuxia.ioc02; public class Person { private Integer id; private String name; public Person() { System.out.println("I'm a constructor"); } public Person(Integer id, String name) { this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
package com.yemuxia.ioc02; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainClass { public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("XmlBean.xml"); Person person = (Person)ctx.getBean("person"); System.out.println(person); } }
2. Define Bean information based on the form of reading configuration class
package com.yemuxia.ioc03; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class TestConfig { @Bean public Person person1(){ return new Person(); } }
package com.yemuxia.ioc03; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import java.util.Arrays; public class MainClass { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestConfig.class); String[] beanNames = context.getBeanDefinitionNames(); Arrays.stream(beanNames).forEach(System.out::println); } }
If it is used in the form of @ bean, the default name of the bean is the method name. If @ Bean(value = "bean name"), the bean name is specified
3. Write @ CompentScan annotation on the configuration class to scan the package
package com.yemuxia.ioc01; import org.springframework.context.annotation.ComponentScan; @ComponentScan("com.yemuxia.ioc01") public class AppConfig { }
package com.yemuxia.ioc01; import org.springframework.stereotype.Controller; @Controller public class TestController { }
package com.yemuxia.ioc01; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); String[] beanDefinationNames = context.getBeanDefinitionNames(); for (String name:beanDefinationNames) { System.out.println("bean Definition information of:"+name); } } }
Exclusion usage excludeFilters
package com.yemuxia.ioc01; import org.springframework.stereotype.Service; @Service public class TestService { }
package com.yemuxia.ioc01; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller; @ComponentScan(basePackages = "com.yemuxia.ioc01", excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class}), @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {TestService.class}) }) public class AppConfig { }
Include usage includeFilters
Note that if you use the included usage, you need to set the useDefaultFilters property to false (true means to scan all)
package com.yemuxia.ioc01; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Controller; @ComponentScan(basePackages = "com.yemuxia.ioc01", includeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class}) }, useDefaultFilters = false) public class AppConfig { }
@ComponentScan. Type of filter type
FilterType.CUSTOM custom type
package com.yemuxia.ioc01; 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; import java.io.IOException; public class TestFilterType implements TypeFilter { @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //Gets the annotation source information of the current class AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); //Gets the source information of the class of the current class ClassMetadata classMetadata = metadataReader.getClassMetadata(); //Gets the resource information of the current class Resource resource = metadataReader.getResource(); System.out.println("Path to class:"+classMetadata.getClassName()); if(classMetadata.getClassName().contains("Dao")) { return true; } return false; } }
package com.yemuxia.ioc01; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; @ComponentScan(basePackages = "com.yemuxia.ioc01", excludeFilters = { @ComponentScan.Filter(type = FilterType.CUSTOM,value = TestFilterType.class) }) public class AppConfig { }
4. Configure the scope object of the Bean
When @ Scope is not specified, all beans are single instance beans and are loaded (the container starts and the instance is created)
package com.yemuxia.ioc03; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @Configuration public class TestConfig { @Bean @Scope(value = "prototype") public Person person1(){ return new Person(); } }
Specify @ Scope as prototype, which means it is multi instance and loaded in lazy mode (the object will not be created when the IOC container is started, but will be created when it is used for the first time)
@Scope specified scope method value
- a) singleton single instance (default)
- b) prototype multi instance
- c) request same request
- d) session the same session level
package com.yemuxia.ioc03; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; @Configuration public class TestConfig { @Bean @Lazy public Person person1(){ return new Person(); } }
Lazy loading @ lazy of beans (mainly for single instance beans. The object will not be created when the container is started, but will only be created when it is used for the first time)
5.@Conditional makes conditional judgment
package com.yemuxia.ioc04; public class TestComponentA { public TestComponentA() { System.out.println("assembly A Construction method of"); } }
package com.yemuxia.ioc04; public class TestComponentB { public TestComponentB() { System.out.println("assembly B Construction method of"); } }
package com.yemuxia.ioc04; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @Configuration public class TestConfig { @Bean public TestComponentA testComponentA(){ return new TestComponentA(); } @Bean @Conditional(value = TestCondition.class) public TestComponentB testComponentB(){ return new TestComponentB(); } }
package com.yemuxia.ioc04; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; public class TestCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //Determine whether there is a component of testComponentA in the container if(context.getBeanFactory().containsBean("testComponentA")) { return true; } return false; } }
package com.yemuxia.ioc04; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import java.util.Arrays; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestConfig.class); String[] beanNames = context.getBeanDefinitionNames(); Arrays.stream(beanNames).forEach(System.out::println); } }
package com.yemuxia.ioc04; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @Configuration public class TestConfig { //@Bean public TestComponentA testComponentA(){ return new TestComponentA(); } @Bean @Conditional(value = TestCondition.class) public TestComponentB testComponentB(){ return new TestComponentB(); } }
If there is an instance of TestComponentA in the container, TestComponentB will be instantiated
6. How to add components to IOC container
- Applicable scenario through @ compentscan + @ controller @ service @ repository @ compent: components written by ourselves can be loaded into the container in this way.
- Import components through @ Bean (applicable to classes importing third-party components)
- Import components through @ import (the id of the imported component is the full class name path)
- The registered component is implemented by implementing the factorybean interface
Import components by @ import
package com.yemuxia.ioc5; public class Car { }
package com.yemuxia.ioc5; public class Cat { }
package com.yemuxia.ioc5; public class Dog { }
package com.yemuxia.ioc5; public class Person { }
package com.yemuxia.ioc5; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata; public class TestBeanDefinitionRegister implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Cat.class); registry.registerBeanDefinition("cat",rootBeanDefinition); } }
package com.yemuxia.ioc5; import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata; public class TestImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { return new String[]{"com.yemuxia.ioc5.Dog"}; } }
package com.yemuxia.ioc5; import org.springframework.context.annotation.Import; @Import(value = {Person.class, Car.class, TestImportSelector.class, TestBeanDefinitionRegister.class}) public class TestConfig { }
package com.yemuxia.ioc5; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import java.util.Arrays; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestConfig.class); String[] beanNames = context.getBeanDefinitionNames(); Arrays.stream(beanNames).forEach(System.out::println); } }
The registered component is implemented by implementing the factorybean interface
package com.yemuxia.ioc6; public class Car { }
package com.yemuxia.ioc6; import org.springframework.beans.factory.FactoryBean; /** * Register components in the container by implementing the FactoryBean interface */ public class CarFactoryBean implements FactoryBean<Car> { @Override public Car getObject() throws Exception { return new Car(); } @Override public Class<?> getObjectType() { return Car.class; } @Override public boolean isSingleton() { return false; } }
package com.yemuxia.ioc6; import org.springframework.beans.factory.FactoryBean; import java.sql.DriverManager; public class DriverFactoryBean implements FactoryBean { private String jdbcUrl; public String getJdbcUrl() { return jdbcUrl; } public void setJdbcUrl(String jdbcUrl) { this.jdbcUrl = jdbcUrl; } @Override public Object getObject() throws Exception { return DriverManager.getDriver(jdbcUrl); } @Override public Class<?> getObjectType() { return java.sql.Driver.class; } @Override public boolean isSingleton() { return true; } }
package com.yemuxia.ioc6; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; @Configuration @ImportResource(locations = {"classpath:beans.xml"}) public class AppConfig { @Bean public CarFactoryBean carFactoryBean(){ return new CarFactoryBean(); } }
<?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="car" class="com.yemuxia.ioc6.Car"/> <bean id="driverFactoryBean" class="com.yemuxia.ioc6.DriverFactoryBean"> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/yemuxia"/> </bean> </beans>
package com.yemuxia.ioc6; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MainClass { public static void main(String[] args) throws Exception { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); Object bean = ctx.getBean("carFactoryBean"); System.out.println(bean); Object bean2 = ctx.getBean("&carFactoryBean"); System.out.println(bean2); System.out.println(bean.getClass()); System.out.println(bean2.getClass()); Object bean3 = ctx.getBean("carFactoryBean"); System.out.println(bean==bean3); CarFactoryBean carFactoryBean = ctx.getBean(CarFactoryBean.class); System.out.println(carFactoryBean); System.out.println(ctx.getBean("driverFactoryBean")); } }
7.Bean initialization method and destruction method
What is the life cycle of a Bean
bean creation initialization destruction method
The container manages the life cycle of beans. We can specify the initialization method and destruction method of beans by ourselves.
- For single instance beans, when the container starts, the bean object is created, and when the container is destroyed, the bean destruction method will also be called
- For multi instance beans, when the container starts, the beans will not be created, but will be created when the beans are obtained, and the destruction of beans is not managed by the IOC container
Single instance bean demo
package com.yemuxia.ioc7; public class Car { public Car() { System.out.println("Car Construction method of.........."); } public void init() { System.out.println("Car Initialization method of......init"); } public void destroy() { System.out.println("Car Destruction method of.....destroy"); } }
package com.yemuxia.ioc7; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages = "com.yemuxia.ioc7") public class AppConfig { @Bean(initMethod = "init",destroyMethod = "destroy") public Car car() { return new Car(); } }
package com.yemuxia.ioc7; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MainClass { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); ctx.close(); } }
Multi instance bean
package com.yemuxia.ioc7; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @Configuration @ComponentScan(basePackages = "com.yemuxia.ioc7") public class AppConfig { @Scope(value = "prototype") @Bean(initMethod = "init",destroyMethod = "destroy") public Car car() { return new Car(); } }
package com.yemuxia.ioc7; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MainClass { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); Car car = ctx.getBean(Car.class); ctx.close(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(car); } }
The initialization and destruction methods of beans are implemented through the two interfaces of InitializingBean and DisposableBean
package com.yemuxia.ioc7; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; public class Person implements InitializingBean,DisposableBean { public Person() { System.out.println("Person Construction method of"); } @Override public void destroy() throws Exception { System.out.println("DisposableBean of destroy()method "); } @Override public void afterPropertiesSet() throws Exception { System.out.println("InitializingBean of afterPropertiesSet method"); } }
package com.yemuxia.ioc7; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @Configuration @ComponentScan(basePackages = "com.yemuxia.ioc7") public class AppConfig { @Scope(value = "prototype") @Bean(initMethod = "init",destroyMethod = "destroy") public Car car() { return new Car(); } @Bean public Person person(){ return new Person(); } }
Annotation methods of @ PostConstruct and @ ProDestory provided by JSR250 specification
package com.yemuxia.ioc7; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; public class Book { public Book() { System.out.println("book Construction method of"); } @PostConstruct public void init() { System.out.println("book of PostConstruct Marking method"); } @PreDestroy public void destory() { System.out.println("book of PreDestory Annotation method"); } }
package com.yemuxia.ioc7; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @Configuration @ComponentScan(basePackages = "com.yemuxia.ioc7") public class AppConfig { @Scope(value = "prototype") @Bean(initMethod = "init",destroyMethod = "destroy") public Car car() { return new Car(); } @Bean public Person person(){ return new Person(); } @Bean public Book book(){ return new Book(); } }
The post processor of beans through Spring's BeanPostProcessor will intercept all bean creation processes
- postProcessBeforeInitialization is called before init method.
- postProcessAfterInitialization is called after the init method.
package com.yemuxia.ioc7; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class TestBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("TestBeanPostProcessor...postProcessBeforeInitialization:"+beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("TestBeanPostProcessor...postProcessAfterInitialization:"+beanName); return bean; } }
package com.yemuxia.ioc7; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @Configuration @ComponentScan(basePackages = "com.yemuxia.ioc7") public class AppConfig { @Scope(value = "prototype") @Bean(initMethod = "init",destroyMethod = "destroy") public Car car() { return new Car(); } @Bean public Person person(){ return new Person(); } @Bean public Book book(){ return new Book(); } @Bean public TestBeanPostProcessor testBeanPostProcessor(){ return new TestBeanPostProcessor(); } }
Execution timing of BeanPostProcessor
populateBean(beanName, mbd, instanceWrapper) initializeBean{ applyBeanPostProcessorsBeforeInitialization() invokeInitMethods{ isInitializingBean.afterPropertiesSet Custom init method } applyBeanPostProcessorsAfterInitialization()method }
8. Assign values to components through @ Value and @ PropertySource
package com.yemuxia.ioc8; import org.springframework.beans.factory.annotation.Value; public class Person { @Value("Sima") private String firstName; @Value("#{28-8}") private Integer age; @Value("${person.lastName}") private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } @Override public String toString() { return "Person{" + "firstName='" + firstName + '\'' + ", age=" + age + ", lastName='" + lastName + '\'' + '}'; } }
person.lastName=Old thief
package com.yemuxia.ioc8; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @Configuration @PropertySource(value = {"classpath:person.properties"}) public class AppConfig { @Bean public Person person() { return new Person(); } }
package com.yemuxia.ioc8; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MainClass { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); Person person = ctx.getBean(Person.class); System.out.println(person.toString()); } }
9. Automatic assembly
Automatic assembly is first assembled according to the type. If multiple components of the same type are found in the IOC container, it is assembled according to the attribute name
Assemble by type
package com.yemuxia.ioc9; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @ComponentScan(basePackages = {"com.yemuxia.ioc9"}) public class AppConfig { @Bean public TestDao testDao2() { TestDao testDao = new TestDao(); testDao.setFlag(2); return testDao; } }
package com.yemuxia.ioc9; public class TestDao { private int flag=1; public int getFlag() { return flag; } public void setFlag(int flag) { this.flag = flag; } @Override public String toString() { return "TestDao{" + "flag=" + flag + '}'; } }
package com.yemuxia.ioc9; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class BaiDuService { @Autowired private TestDao testDao; @Override public String toString() { return "BaiDuService{" + testDao + '}'; } }
package com.yemuxia.ioc9; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MainClass { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); //byName or byType is used when testing @ AutoWired (byType is used by default, and byName is used when multiple bean s of the same type are found) //You need to specify the name of the assembly. Specify the assembly name through @ Qualifier BaiDuService baiDuService = ctx.getBean(BaiDuService.class); System.out.println(baiDuService); } }
Assemble by property (multiple bean s of the same type)
package com.yemuxia.ioc9; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @ComponentScan(basePackages = {"com.yemuxia.ioc9"}) public class AppConfig { @Bean public TestDao testDao2() { TestDao testDao = new TestDao(); testDao.setFlag(2); return testDao; } @Bean public TestDao testDao3() { TestDao testDao = new TestDao(); testDao.setFlag(3); return testDao; } }
This code reports an error. The reason for the error is that there are multiple bean instances of the same type in the Spring container, which will be assembled according to the instance name during automatic assembly. However, no matching instance name (testDao) was found in the container. Therefore, an error is reported.
If we do not find a matching instance name in the container, an exception will be thrown during assembly tuling. testautowired. Turing Dao 'available if we don't want to throw exceptions, we need to specify required as false
Use @ Qualifier("testDao") to specify the assembled components
package com.yemuxia.ioc9; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @Service public class BaiDuService { @Autowired @Qualifier(value = "testDao3") private TestDao testDao; @Override public String toString() { return "BaiDuService{" + testDao + '}'; } }
Add the @ Primary annotation to the @ Bean on the configuration class
package com.yemuxia.ioc9; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Primary; @ComponentScan(basePackages = {"com.yemuxia.ioc9"}) public class AppConfig { @Bean public TestDao testDao2() { TestDao testDao = new TestDao(); testDao.setFlag(2); return testDao; } @Bean @Primary public TestDao testDao3() { TestDao testDao = new TestDao(); testDao.setFlag(3); return testDao; } }
@The difference between Autowired, @ Resource, @ Inject:
- 1. @ Autowired comes with spring, @ Inject is implemented by JSR330 specification, @ Resource is implemented by JSR250 specification, and different packages need to be imported
- 2. The usage of @ Autowired and @ Inject are basically the same, except that @ Autowired has a request attribute
- 3. @ Autowired and @ Inject are matched by type by default, and @ Resource is matched by name
- 4. @ Autowired needs to be used with @ Qualifier if it needs to match by name, @ Inject and @ Named
10. When the components written by yourself need to use the underlying components of spring ioc, such as ApplicationContext, etc
We can do this by implementing the XXXAware interface
package com.yemuxia.ioc10; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages = "com.yemuxia.ioc10") public class AppConfig { }
package com.yemuxia.ioc10; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanNameAware; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class TestCompent implements ApplicationContextAware,BeanNameAware { private ApplicationContext applicationContext; @Override public void setBeanName(String name) { System.out.println("current bean name is :["+name+"]"); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }
package com.yemuxia.ioc10; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MainClass { public static void main(String[] args) { AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class); } }
11. Activate and identify different beans according to the environment through @ Profile annotation
@If the Profile is identified on the class, the entire configuration class will take effect only if the current environment matches @ if the Profile is identified on the Bean, only the Bean of the current environment will be activated
No bean marked @ Profile can be activated in any environment
package com.yemuxia.ioc11; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; import org.springframework.util.StringValueResolver; import javax.sql.DataSource; @Configuration @PropertySource(value = {"classpath:ds.properties"}) public class AppConfig implements EmbeddedValueResolverAware { @Value("${ds.username}") private String userName; @Value("${ds.password}") private String password; private String jdbcUrl; private String classDriver; @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { this.jdbcUrl = resolver.resolveStringValue("${ds.jdbcUrl}"); this.classDriver = resolver.resolveStringValue("${ds.classDriver}"); } @Bean @Profile(value = "test") public DataSource testDs() { return buliderDataSource(new DruidDataSource()); } @Bean @Profile(value = "dev") public DataSource devDs() { return buliderDataSource(new DruidDataSource()); } @Bean @Profile(value = "prod") public DataSource prodDs() { return buliderDataSource(new DruidDataSource()); } private DataSource buliderDataSource(DruidDataSource dataSource) { dataSource.setUsername(userName); dataSource.setPassword(password); dataSource.setDriverClassName(classDriver); dataSource.setUrl(jdbcUrl); return dataSource; } }
ds.username=root ds.password=123456 ds.jdbcUrl=jdbc:mysql://localhost:3306/skq ds.classDriver=com.mysql.jdbc.Driver
package com.yemuxia.ioc11; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MainClass { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.getEnvironment().setActiveProfiles("test","dev"); ctx.register(AppConfig.class); ctx.refresh(); printBeanName(ctx); } private static void printBeanName(AnnotationConfigApplicationContext ctx){ for(String beanName:ctx.getBeanDefinitionNames()) { System.out.println("In container BeanName: "+beanName); } } }
Method of activating switching environment
- Method 1: switch through runtime jvm parameters
-Dspring.profiles.active=test|dev|prod - Method 2: activate by code