springboot e-commerce project mall4j( https://gitee.com/gz-yami/mall4j)
1. bean registration
We have a Person class
public class Person { private Integer age; private String name; public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person [age=" + age + ", name=" + name + "]"; } }
1.1 traditional bean registration
New 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="person" class="com.opgame.spring.Person"> <property name="age" value="18"/> <property name="name" value="Zhang San"/> </bean> </beans>
Use the person object to test
@Test public void testBean() { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Person person = (Person)context.getBean("person"); System.out.println(person); }
1.2 using annotation instead of xml registration
Create a java class with @ Configuration and register with @ Bean
@Configuration // Tell spring that this is a config class public class BeansConfig { // Register a bean for the container. The type is the return value type. The default id is the method name. Set the id in the bean annotation @Bean("person") public Person person() { Person person = new Person(); person.setAge(20); person.setName("Li Si"); return person; } }
Use the person object to test
@Test public void testBean() { ApplicationContext context = new AnnotationConfigApplicationContext(BeansConfig.class); Person person = (Person)context.getBean("person"); System.out.println(person); }
2 exclude,include filter
In traditional spring mvc projects, in order to make transactions effective, we usually use context XML for the exclude @Controller class in MVC XML includes @ controller. When we use some third-party class libraries, we sometimes need to scan the exclusion code of some classes. What should we do?
2.1 traditional xml exclusion and import scan classes
context.xml (requires context namespace)
<context:component-scan base-package="com.opgame"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
mvx.xml
<!-- use-default-filters default tureļ¼Default scan@Component @Repository @Service @Controller --> <context:component-scan base-package="com.opgame" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
2.2 exclude and import scan classes in the form of annotations
@ComponentScan annotation usage
- value: Specifies the package to scan
- excludeFilters = Filter []: Specifies the rules to exclude those components during scanning
- includeFilters = Filter []: specifies which components only need to be included during scanning
- useDefaultFilters: whether to use the default Filters
Filter
- FilterType.ANNOTATION: according to the annotation
- FilterType.ASSIGNABLE_TYPE: according to the given type
- FilterType.ASPECTJ: use ASPECTJ expressions
- FilterType.REGEX: specify with regular
- FilterType.CUSTOM: use custom rules
- classes: ANNOTATION,ASSIGNABLE_ Class given by type and CUSTOM
- pattern: the expression given by ASPECTJ and REGEX
@Configuration // Tell spring that this is a config class @ComponentScan(value="com.opgame",useDefaultFilters=false, includeFilters= { @Filter(type=FilterType.ANNOTATION,classes= {Controller.class}) }, excludeFilters= { @Filter(type=FilterType.ASSIGNABLE_TYPE,classes= {PersonController.class}) }) public class BeansConfig{ }
Custom rules
// Implementation org springframework. core. type. filter. Typefilter interface public class BeanTypeFilter implements TypeFilter{ /** * @param metadataReader Get the metadata of the current class scanned by spring * @param metadataReaderFactory The factory for obtaining metadata is used to obtain the information of other classes */ public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { // Get the meta information of the current class annotation AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); // Gets the class information of the current class ClassMetadata classMetadata = metadataReader.getClassMetadata(); // Gets the resource (classpath) of the current class Resource resource = metadataReader.getResource(); // If the current class name contains person, the configuration is successful if(classMetadata.getClassName().contains("person")) { return true; } return false; } }
3. Scope and lazy loading
3.1 xml
<!-- default scope="singleton" Single case--> <!-- lazy-init="true" Objects are created only when needed. The default value is spring Created on initialization--> <bean id="person" class="com.opgame.spring.Person" scope="singleton" lazy-init="true"> <property name="age" value="18"/> <property name="name" value="Zhang San"/> </bean>
3.2 notes
@Lazy @Scope("singleton") @Bean("person") public Person person() { Person person = new Person(); person.setAge(20); person.setName("Li Si"); return person; }
4. Register according to conditions
Sometimes, when we write a framework or code, we need to switch to different implementation methods in different environments. So when to load the implementation of that class, spring provides us with this annotation
Use the @ Conditional annotation in spring to load classes on demand.
@Conditional({ LinuxCondition.class }) public Person person1() { Person person = new Person(); person.setAge(18); person.setName("Li Xiaosi"); return person; }
// Implementation org springframework. context. annotation. Condition interface public class LinuxCondition implements Condition{ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // Get beanfactory used by ioc ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); // Get class loader ClassLoader classLoader = context.getClassLoader(); // Get current environment Environment environment = context.getEnvironment(); // Get bean registration class BeanDefinitionRegistry registry = context.getRegistry(); // Determine whether the person object is included boolean hasPerson = registry.containsBeanDefinition("person"); if (!hasPerson) { return false; } // Determine whether it belongs to linux Environment if(environment.getProperty("os.name").contains("linux")) { return true; } return false; } }
You can also view Environment related notes by setting vm arguments when starting the program
-Dos.name=linux
You can also
In spring boot, @ ConditionalOnMissingBean(name="xxx") @ConditionalOnMissingBean(xxx.class) can also be used to determine whether to register when there are no classes or methods.
5. Use import to register
Multiple existing classes
class Blue {} class Color {} class Red {}
5.1 simple registration
When we need to register without parameters, we can use @ import to register, such as:
@Configuration @Import({Blue.class,Red.class}) public class BeansConfig { }
Where bean id is the full name of the class, such as com opgame. spring. bean. Blue com. opgame. spring. bean. Red
amount to
@Configuration public class BeansConfig { @Bean("com.opgame.spring.bean.Blue") public Blue blue() { return new Blue(); } @Bean("com.opgame.spring.bean.Red") public Red red() { return new Red(); } }
5.2 class name registration using ImportSelector
// Custom logic returns the components to be imported // Implementation org springframework. context. annotation. Importselector interface public class BeanImportSelector implements ImportSelector{ /** * importingClassMetadata: You can obtain all annotation meta information of the currently annotated @ Import annotation * Beansconfig. In the current example Meta information of all annotations of class */ public String[] selectImports(AnnotationMetadata importingClassMetadata) { // null return is not allowed return new String[] {"com.opgame.spring.bean.Blue","com.opgame.spring.bean.Red"}; } }
@Configuration @Import({BeanImportSelector.class}) public class BeansConfig { }
5.3 ImportBeanDefinitionRegistrar registers a bean into the container
At this time, the bean definition is registered, that is, the bean definition information, and spring will register the bean according to the bean definition information! That is, there is no bean registered at this time!!!
// Implementation org springframework. context. annotation. Importbeandefinitionregistrar interface public class BeansImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar{ /** * importingClassMetadata: Annotation information of the current config class (beansConfig) * registry: Bean Register the class. You can call beandefinitionregistry here for all beans that need to be added to the container Register with the registerbeandefinition() method */ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean hasBlue = registry.containsBeanDefinition("com.opgame.spring.bean.Blue"); boolean hasRed = registry.containsBeanDefinition("com.opgame.spring.bean.Red"); // If there are red and blue, a Color object with id Color is registered if (hasBlue && hasRed) { RootBeanDefinition beanDefinition = new RootBeanDefinition(Color.class); registry.registerBeanDefinition("color", beanDefinition); } } }
@Configuration @Import({Blue.class,Red.class,BeansImportBeanDefinitionRegistrar.class}) public class BeansConfig { }
6. Implement factorybean <? > Interface registration bean
// Implementation org springframework. beans. factory. Factorybean interface public class PersonFactoryBean implements FactoryBean<Person>{ // Construct person object public Person getObject() throws Exception { return new Person(); } // Gets the type of the current object public Class<?> getObjectType() { return Person.class; } // Is it a single instance public boolean isSingleton() { return true; } }
@Configuration public class BeansConfig { @Bean public PersonFactoryBean personFactoryBean() { return new PersonFactoryBean(); } }
Use the person object to test
@Test public void testBean() { ApplicationContext context = new AnnotationConfigApplicationContext(BeansConfig.class); context.getBean("personFactoryBean").getClass(); // com.opgame.spring.Person // The & symbol is required to get the bean object constructed by the factory Person person = (Person)context.getBean("&personFactoryBean"); // If & is not used, the factory itself is obtained PersonFactoryBean personFactoryBean = (PersonFactoryBean)context.getBean("personFactoryBean"); System.out.println(person); }
7 created by BeanDefinitionBuilder
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(User.class); builder.addPropertyValue("id", 1); builder.addPropertyValue("name", "Li Si"); registry.registerBeanDefinition("user", builder.getBeanDefinition());
springboot e-commerce project mall4j( https://gitee.com/gz-yami/mall4j)