Environment set up

Annotation injection is simpler than XML injection. Annotation injection also needs to add a spring-context package on the basis of the former, which is also a common way in practical development.

Prepare the required Jar packages

Component registration for Spring annotations

Spring provides a number of annotation configurations so that components can be registered using annotations. The following is a typical example of an annotation used in Spring.

@ ComponentScan and @ Configurable

The original XML approach

<? The XML version = "1.0" encoding = "utf-8"? > <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <! <context:component-scan base-package="model"></context:component-scan> </beans>Copy the code

The @componentScan (” Model “) specifies the parameters to be scanned for this configuration class.

package config; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.context.annotation.ComponentScan; import model.Product; /** * @Configurable: The annotation is to annotate that the class is a configuration class * @ComponentScan: * @author GaoYang */ @componentScan ("model") public class MainConfig {}Copy the code

@Component

Use this annotation to register the Java object @Component in the Ioc container. The @Component annotation assigns values to properties along with the @Value annotation.

/** @componnt specifies the id of this object. */ @Component(" Students ") public class Student {@value ("01") private int sid; @value (" Value ") private String name; @value (" male ") private String sex;Copy the code

The configuration class

/** * @Configurable: The annotation is to annotate that the class is a configuration class * @ComponentScan: * @author GaoYang */ @componentScan ("model") public class MainConfig {}Copy the code

Use @Configuration for injection

@Component("students") public class Student { @Value("01") private int sid; @value (" Value ") private String name; @value (" male ") private String sex; public Student() { super(); } public Student(int sid, String name, String sex) { super(); this.sid = sid; this.name = name; this.sex = sex; } public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "Student [sid=" + sid + ", name=" + name + ", sex=" + sex + "]"; }}Copy the code

test

@Bean

Using the @bean annotation that can be annotated in our Spring registry class, the method that creates the object can be created by a method that returns a value for the object and assigns values to its properties through the constructor.

@componentScan ("model") public class MainConfig {// The default id is @componentScan () public Product product1() { Return new Product(" hashd", "hashd",1); } @bean ("product2") public Product product2() {return new Product(" Product ","hashd",1); }}Copy the code

Java Bean object

public class Product { private String name; private String price; private int num; public Product() { super(); } public Product(String name, String price, int num) { super(); this.name = name; this.price = price; this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } @Override public String toString() { return "Product [name=" + name + ", price=" + price + ", num=" + num + "]"; }}Copy the code

test

@TypeFilter

The @TypeFilter annotation filters some resources by setting conditions. We can filter some resources from being loaded into the IOC container. It is used in the @ComponentScan annotation, which is passed by the excludeFilters parameter. ExcludeFilters are an array that can be set to multiple @TypeFilters.

@ the TypeFilter grammar

@componentScan (value = "model",excludeFilters = {// Filter type = @filter (type = "model") FilterType.ANNOTATION,classes = {Controller.class}), // filtertype. ASSIGNABLE_TYPE is defined by the given @filter (type = filtertype. ASSIGNABLE_TYPE,classes = {product.class}), / / FilterType ASPECTJ based on regular expressions @ Filter (type = FilterType ASPECTJ, classes = {" "}). / / FilterType. CUSTOM using CUSTOM rules @ Filter (type = FilterType. CUSTOM classes = {TypeFilterImp. Class})}) public class MainConfig { // @Bean == <bean></bean> }Copy the code

@filterType. CUSTOM CUSTOM rules

To use a custom rule, we must create a rule class that implements TypeFilter and match. The filter will be loaded based on the return value of the match method. If true, the filter will not be loaded if false.

/** * MetadataReader: /** * MetadataReaderFactory: */ @override public Boolean match(MetadataReader, MetadataReader, MetadataReaderFactory MetadataReaderFactory) throws IOException {// Get the information AnnotationMetadata Mr = metadataReader.getAnnotationMetadata(); / / get the current class is scanning information ClassMetadata ClassMetadata = metadataReader. GetClassMetadata (); / / get the current class of Resource information Resource Resource. = metadataReader getResource (); / / get the current class name String className = classMetadata, getClassName (); System.out.println("----"+className); // Contains contains "er" if(classname. contains("er")) {return true; } return false; }}Copy the code

@Scope

Spring creates objects that are singletons by default and are described by @scope (Scope = “singleton”). Scope also has prototype, Request, Session, and Global Session scopes.

The effect of each scope

  • Singleton singleton pattern, with one and only one instance globally. (Default value)
  • Prototype: a new instance is generated each time a Bean is fetched.
  • Request indicates that a new bean is generated for each HTTP request, and the bean is valid only in the current HTTP request. Example To use request, session, and Global session, perform the following configuration in the web. XML file that initializes the Web: If you are using a Web container with Servlet 2.4 and above, you simply add the following ContextListener to the web. XML XML declaration file of your Web application:
<web-app> ... <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> . </web-app>Copy the code
  • The session scope means that a new bean is generated for each HTTP request and is valid only for the current HTTP session
  • The Global Session scope is similar to the standard HTTP Session scope, but only makes sense in portlet-based Web applications. The Portlet specification defines the concept of a global Session, which is shared by all the different portlets that make up a Portlet Web application. Beans defined in the Global Session scope are limited to the lifecycle of the global Portlet session. If you use the Global Session scope on the Web to identify beans, the Web will automatically use it as a session type.

Case presentation

singleton

@Configurable @ComponentScan("model") public class MainConfig { /** * @Scope * prototype: @scope ("prototype") * singleton: @scope ("person") * Request: create one instance at a time * session: @scope ("singleton") @bean public Product Product () {system.out.println (" this instance has been created "); Return new Product(" hashd", "hashd",1); }}Copy the code

The test code

public class text { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new  AnnotationConfigApplicationContext(MainConfig.class); System.out.println("Ioc container created!" ); Product bean1 = applicationContext.getBean(Product.class); Product bean2 = applicationContext.getBean(Product.class); System.out.println(bean1== bean2); }}Copy the code

As you can see in the figure below, bean1 == bean2

Layz-bean

The @layz annotation allows the container not to register the container when it is created, but to register the bean object when it is first called. At this point, the object is still created in singleton mode!

Use the syntax

// cache@componentScan ("model") public class MainConfig {/** * The c64X works without any additional information, and provides a different information system for every component. * */ @lazy @bean public Product Product () {system.out.println (" This instance has been created "); Return new Product(" hashd", "hashd",1); }Copy the code

test

@Conditional

The @Conditional annotation is to register according to the specified conditions. I need to create a configuration class with the configuration conditions. If the conditions are met, I will register; if the conditions are not met, I will not register.

grammar

The configuration class

@Configurable public class MainConfig { @Conditional({winCondition.class}) @Bean("wind") public Product wind() { System.out.println(" The instance has been created "); Return new Product(" zhang SAN ","wind",1); }Copy the code

The Condition class must implement the Condition interface and be added as an implemented method!

public class winCondition implements Condition{ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata arg1) { Environment environment = context.getEnvironment(); String Property = environment.getProperty("os.name"); // Get the name of the current operating system. if(property.contains("Windows")) { return true; } return false; }}Copy the code

case

Components need to be deregistered based on the current operating system.

/ / configuration class @ Configurable @ Import (Hero. Class) public class MainConfig {/ / Windows @ Conditional ({winCondition. Class}) @bean ("wind") public Product wind() {system.out.println (" this instance has been created "); Return new Product(" zhang SAN ","wind",1); } @conditional ({linuxcondition.class}) @bean (" Linux ") public Product Linux () {return new The Product (" bill ", "Linux", 2); }}Copy the code

Conditional configuration class

Public class implements Condition{// implements Condition; Return true @override public Boolean matches(ConditionContext context, AnnotatedTypeMetadata arg1) { Environment environment = context.getEnvironment(); String property = environment.getProperty("os.name"); if(property.contains("Windows")) { return true; } return false; }}Copy the code
Public class linuxCondition implements Condition{/** * ConditionContext */ @override public Boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {/ / 1 / / Linux system, also can get used to the ioc bean factory ConfigurableListableBeanFactory the beanFactory = context.getBeanFactory(); ClLoader = context.getClassLoader(); Environment = context.getenvironment (); String property = environment.getProperty("os.name"); BeanDefinitionRegistry = context.getregistry (); // BeanDefinitionRegistry = context.getregistry (); if(property.contains("Linux")) { return true; } return false; }Copy the code

The test…

@import

  • @import can only be used on classes. @import implements a quick Import to add instances to Spring’s IOC container
  • The @import annotation can be used to Import third party packages. Of course, the @bean annotation can also be used, but the @import annotation is a more convenient way to Import quickly
  • The @import annotation can be used in three ways

First use: fill in the class array directly

Fill in the corresponding class array directly. The class array can have 0 to more than one. The corresponding import beans will be added to the Spring container, where the bean name is the full class name of the class, such as com.yc. The name of the class

@import ({class name. Class, class name. Class... }) public class TestDemo { }Copy the code

The second use: ImportSelector

The premise of this method is that a class implements the ImportSelector interface. If I were to use this method, the target object would be Myclass. The analysis is as follows: Create Myclass and implement the ImportSelector interface

Public class Myclass implements mySelector @override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[0]; // Select * from selectImports; // select * from selectImports; AnnotationMetadata represents all annotated information currently annotated by @import. SelectImports can return an empty array but not null.Copy the code

The first step is to create Myclass and implement the ImportSelector interface, which is used to demonstrate adding a full class name to its return value

public class Myclass implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{"com.yc.Test.TestDemo3"}; }}Copy the code

Step 2: Write the TestDemo class and label the Myclass class using ImportSelector

@Import({TestDemo2.class,Myclass.class}) public class TestDemo { @Bean public AccountDao2 accountDao2(){ return new AccountDao2(); }}Copy the code

Step 3: Write component test classes in the print container

Public class AnnotationTestDemo {public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(TestDemo.class); The parameters of the representative / / here to do operation class String [] beanDefinitionNames = applicationContext. GetBeanDefinitionNames (); for (String name : beanDefinitionNames){ System.out.println(name); }}}Copy the code

The third kind of usage: ImportBeanDefinitionRegistrar way

ImportSelector is also an interface, similar to the second ImportSelector usage, with 80% similarity, except that this usage compares custom registrations, as follows:

Public class Myclass2 implements ImportBeanDefinitionRegistrar {/ / the method to realize the default empty @ Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry BeanDefinitionRegistry) {}} AnnotationMetadata, like the ImportSelector parameter before it, represents all annotation information currently annotated by @importCopy the code

Step 2: Write code to customize the registration bean

public class Myclass2 implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry BeanDefinitionRegistry) {// Specify bean definition information (including bean type, scope...) RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestDemo4.class); / / register a bean bean name (id) specified beanDefinitionRegistry. RegisterBeanDefinition (" TestDemo4444, "rootBeanDefinition); }}Copy the code

Step 3: write TestDemo class and marked use ImportBeanDefinitionRegistrar Myclass2 classes

@Import({TestDemo2.class,Myclass.class,Myclass2.class}) public class TestDemo { @Bean public AccountDao2 accountDao222(){ return new AccountDao2(); }}Copy the code

@FactoryBean

Writing configuration classes

@configuration Public class SpringConfiguration {// If there is no @bean annotation, then the id injected into the container is the method name (i.e., myFactoryBean), but if the displayed value is given, then it is factoryBean @bean ("factoryBean") public injected into the container MyFactoryBean myFactoryBean(){ return new MyFactoryBean(); }}Copy the code

The test class

public class SpringDemo { @Test public void springTest01() throws Exception { AnnotationConfigApplicationContext context  = new AnnotationConfigApplicationContext(SpringConfiguration.class); Object factoryBean01 = Context.getBean ("factoryBean"); System.out.println(" The type actually injected into the container is :" + factoryBean01.getClass()); Object factoryBean02 = context.getBean("factoryBean"); System.out.println(" Is an object injected into a container a singleton :" + (factoryBean01 == factoryBean02)); Object factoryBean03 = context.getBean("&factoryBean"); System.out.println(" If you want to get the object of MyFactoryBean, use the & prefix :" + factoryBean03 "); / / the output to print all the name String Bean in the Spring [] beanDefinitionNames = context. GetBeanDefinitionNames (); for (String beanDefinitionName : beanDefinitionNames) { System.out.println(beanDefinitionName); }}}Copy the code

The last

Thank you for reading here, the article has any shortcomings please correct, feel the article is helpful to you remember to give me a thumbs up, every day will share Java related technical articles or industry information, welcome to pay attention to and forward the article!