preface

The traditional Spring approach of using.xml files to inject beans or to configure AOP or things has two disadvantages:

1. If everything was configured in an. XML file, the. XML file would be huge. If you separate the.xml files as required, the.xml files will be very large. In short, this makes the configuration file less readable and maintainable.

2. Switching between.java files and.xml files during development is cumbersome, and this mental incoherence reduces the efficiency of development. To address both of these issues, Spring has introduced annotations that are tightly integrated with Java beans in the form of “@xxx”, greatly reducing the size of configuration files and increasing the readability and cohesiveness of Java beans.

Without annotations:

Take a look at an example of Spring without annotations and change it to an annotated version so you can see the difference between using and not using annotations.

Define a tiger:

package com.spring.model; public class Tiger { private String tigerName="TigerKing"; public String toString(){ return "TigerName:"+tigerName; }}Copy the code

Define another monkey:

package com.spring.model; public class Monkey { private String monkeyName = "MonkeyKing"; public String toString(){ return "MonkeyName:" + monkeyName; }}Copy the code

Define a zoo:

package com.spring.model; public class Zoo { private Tiger tiger; private Monkey monkey; public Tiger getTiger() { return tiger; } public void setTiger(Tiger tiger) { this.tiger = tiger; } public Monkey getMonkey() { return monkey; } public void setMonkey(Monkey monkey) { this.monkey = monkey; } public String toString(){ return tiger + "\n" + monkey; }}Copy the code

The spring configuration file reads:

<? The 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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd "> < bean id =" zoo "class =" com. Spring. Model. The zoo "> <property name="tiger" ref="tiger" /> <property name="monkey" ref="monkey" /> </bean> <bean id="tiger" class="com.spring.model.Tiger" /> <bean id="monkey" class="com.spring.model.Monkey" /> </beans>Copy the code

Test method:

Public class TestAnnotation {/** * without annotations */ @test public void Test (){// Read the configuration file ApplicationContext CTX =new ClassPathXmlApplicationContext("applicationContext2.xml"); Zoo zoo=(Zoo) ctx.getBean("zoo"); System.out.println(zoo.toString()); }}Copy the code

It’s all familiar. I’ll just review it.

1, the @autowired

@autoWired, as the name implies, is an Autowired device that removes properties from getters/setters and bean properties in Java code. Of course, getters look at individual needs and should be reserved if private properties need to be made available externally.

By default, @AutoWired looks for matching beans in the container in a type-matching fashion, and when there is one and only one matching Bean, Spring injects it into the variables of the @AutoWired annotation.

So, to introduce the @autowired annotation, let’s take a look at what the Spring configuration file says:

1 <? The XML version = "1.0" encoding = "utf-8"? > 2 <beans 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  5 xmlns:p="http://www.springframework.org/schema/p" 6 xmlns:context="http://www.springframework.org/schema/context" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 9 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context 10 http://www.springframework.org/schema/context/spring-context-3.0.xsd "> 11 12 13" context: component - scan base-package="com.spring" /> 14 15 <bean id="zoo" class="com.spring.model.Zoo" /> 16 <bean id="tiger" class="com.spring.model.Tiger" /> 17 <bean id="monkey" class="com.spring.model.Monkey" /> 18 19 </beans>Copy the code

<context:component-scan base-package=” XXX “/> is the simplest. Spring will automatically scan for annotations in the XXX path.

In line 15, the tiger and monkey properties of zoo should be injected. Getters/setters can also be removed from zoo. Java:

package com.spring.model; import org.springframework.beans.factory.annotation.Autowired; public class Zoo { @Autowired private Tiger tiger; @Autowired private Monkey monkey; public String toString(){ return tiger + "\n" + monkey; }}Copy the code

What the @AutoWired annotation means here is that when Spring finds the @Autowired annotation, it will automatically find the Bean matching it in the code context (type matching by default) and inject it in the appropriate place.

One detail is that if there are two properties in the bean, what happens if zoo. Java removes the getter/setter for the property and uses the @AutoWired annotation to annotate both properties? The answer is that Spring looks for the getters/setters for these two properties in zoo.java in an XML-first manner, resulting in an error when initializing the bean.

OK, if I remove lines 16 and 17 from the.xml file and run it again, it will raise an exception:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'zoo': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.spring.model.Tiger com.spring.model.Zoo.tiger; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.spring.model.Tiger] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.spring.test.TestAnnotation.test(TestAnnotation.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.spring.model.Tiger com.spring.model.Zoo.tiger; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.spring.model.Tiger] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
    ... 36 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.spring.model.Tiger] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:920)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:789)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
    ... 38 more

Copy the code

Because the @autoWired annotation is looking for a Bean, the Tiger and Monkey Bean definitions have been removed, so it is not a Bean, and it is understandable that the Spring container cannot find it. So, if the property can’t be found and I don’t want the Spring container to throw an exception, I’m just showing null, okay? Set @AutoWired’s required attribute to false:

package com.spring.model; import org.springframework.beans.factory.annotation.Autowired; public class Zoo { @Autowired(required=false) private Tiger tiger; @Autowired(required=false) private Monkey monkey; public String toString(){ return tiger + "\n" + monkey; }}Copy the code

At this point, the Tiger and Monkey properties are not found, and the Spring container no longer throws an exception but treats them as null.

Qualifier (specify the name of the injection Bean)

If there is more than one matching Bean in the container, the name of the Bean can be qualified with the @qualifier annotation, as shown in the following example:

Define a Car interface:

package com.spring.service;

public interface ICar {
    
    public String getCarName();
}
Copy the code

Two implementation classes BMWCar and BenzCar:

package com.spring.service.impl; import com.spring.service.ICar; public class BMWCar implements ICar{ public String getCarName(){ return "BMW car"; }}Copy the code
package com.spring.service.impl; import com.spring.service.ICar; public class BenzCar implements ICar{ public String getCarName(){ return "Benz car"; }}Copy the code

Write another CarFactory that references CAR (no @qualifier annotation here) :

package com.spring.model; import org.springframework.beans.factory.annotation.Autowired; import com.spring.service.ICar; public class CarFactory { @Autowired private ICar car; public String toString(){ return car.getCarName(); }}Copy the code

Configuration file:

<? The 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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd "> < context: component - scan base-package="com.spring" /> <! - Autowired annotations with the Qualifier annotations - > < bean id = "carFactory" class = "com. Spring. Model. CarFactory" / > < bean id = "bmwCar" class="com.spring.service.impl.BMWCar" /> <bean id="benz" class="com.spring.service.impl.BenzCar" /> </beans>Copy the code

Test method:

@test public void test1(){ApplicationContext CTX =new ClassPathXmlApplicationContext("applicationContext2.xml"); CarFactory carFactory=(CarFactory) ctx.getBean("carFactory"); System.out.println(carFactory.toString()); }Copy the code

The Car interface has two implementation classes, and Spring doesn’t know which implementation class to refer to.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'carFactory': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: 
Could not autowire field: private com.spring.service.ICar com.spring.model.CarFactory.car; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No unique bean of type [com.spring.service.ICar] is defined: expected single matching bean but found 2: [bmwCar, benz]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.spring.test.TestAnnotation.test1(TestAnnotation.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.spring.service.ICar com.spring.model.CarFactory.car; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.spring.service.ICar] is defined: expected single matching bean but found 2: [bmwCar, benz]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
    ... 36 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.spring.service.ICar] is defined: expected single matching bean but found 2: [bmwCar, benz]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:796)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
    ... 38 more
Copy the code

There are two common solutions to this problem: (1) Remove one of the implementation classes from the configuration file. Spring automatically searches the Base-package for the implementation class of the Car interface and finds that there is only one implementation class. (2) What if there are more than one implementation class? Use the @qualifier annotation to specify the name of the Bean:

package com.spring.model; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import com.spring.service.ICar; public class CarFactory { @Autowired @Qualifier("bmwCar") private ICar car; public String toString(){ return car.getCarName(); }}Copy the code

A Bean named “bmwCar” is injected here.

3, the Resource

The @resource annotation is very similar to the @autowired annotation. This is a simple example: package com.spring.model; import javax.annotation.Resource; public class Zoo1 { @Resource(name="tiger") private Tiger tiger; @Resource(type=Monkey.class) private Monkey monkey; public String toString(){ return tiger + "\n" + monkey; }}Copy the code

Here’s a more detailed use of the @resource assembly sequence:

(1) there is no content behind @resource. By default, the name attribute is used to match the bean

(2) If name or type is specified, match the bean according to the specified type

(3) If name and type are specified, the bean will be matched according to the specified name and type. Any mismatch will be reported

Then, let’s make a distinction between @autowired and @Resource annotations: @Autowired is a Spring annotation, @resource is a J2EE annotation, @Autowired is a J2EE annotation. Spring belongs to a third party. J2EE is Java’s own property. Therefore, it is recommended to use the @Resource annotation to reduce the coupling between your code and Spring.

4, the Service

This example can be further simplified because there are still three beans in the spring configuration file on lines 15 to 17. The next step is to remove these beans as well, leaving the Spring configuration file with only one auto-scan tag, increasing the cohesion of Java code and further reducing the configuration file size.

To continue simplifying, use @service. Take a look at the configuration file first, deleted entirely, of course:

<? The 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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd "> < context: component - scan base-package="com.spring" /> </beans>Copy the code

Doesn’t it feel good? At least I think so. Java, the rest of the monkey. Java and tiger. Java are the same:

package com.spring.model; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class Zoo { @Autowired private Tiger tiger; @Autowired private Monkey monkey; public String toString(){ return tiger + "\n" + monkey; }}Copy the code

Zoo.java thus exists in the Spring container as “Zoo”, which can be obtained through the ApplicationContext’s getBean(” Zoo “) method. The @service annotation does two things: (1) Declare zoo. Java to bea bean. This is important because zoo. Java is a bean, so other classes can use @AutoWired to inject Zoo as a member variable. Java in the bean id is “Zoo”, that is, the class name and lowercase first letter.

What if, instead of using this form, I want zoo. Java to be named “Zoo” in the Spring container?

package com.spring.model; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; @Service("Zoo") @Scope("prototype") public class Zoo { @Autowired private Tiger tiger; @Autowired private Monkey monkey; public String toString(){ return tiger + "\n" + monkey; }}Copy the code

In this way, zoo.java can be obtained through the getBean(“Zoo”) method of ApplicationContext.

I’ve also added an @scope annotation here, which should make sense. Since Spring produces beans that are singletons by default, what if I don’t want to use singletons? I can configure the scope attribute inside the bean in the XML file. Same thing with annotations, @scope. Default is “singleton”, “prototype”, which means a new one comes out every time.

Use annotations to construct the IoC container. Use annotations to register beans with the Spring container. You need to register <context: Component-scan Base-Package = “pagkage1[,pagkage2,… pagkageN]” /> in applicationContext.xml

For example, specify a package in base-package

<context:component-scan base-package="cn.gacl.java"/>
Copy the code

Java package and its subpackages, if a class with a specific annotation (@Component/ @repository / @service /@Controller) on its head, will register the object as a Bean in the Spring container. You can also specify multiple packages in <context:component-scan base-package= “” />, for example:

< context: component – scan base – package = “cn. Gacl. Dao. Impl, cn. Gacl. Service. Impl, cn. Gacl. Action” / > multiple packages commas.

1. @ Component

@Component is a common form for all spring-managed components. The @Component annotation can be placed on the head of a class; @Component is not recommended.

2, @ Controller

@Controller corresponds to the presentation Bean, i.e. Action, for example:

@controller @scope ("prototype") public class UserAction extends BaseAction<User>{... }Copy the code

Using the @Controller annotation to identify the UserAction indicates that the UserAction is to be managed by the Spring container. There will be an action named “UserAction” in the Spring container, which is named after the UserAction class name.

Note: If @controller does not specify its value [@controller], the default bean name is lowercase, If value [@controller (value=”UserAction”)] or [@controller (“UserAction”)] is specified, value is used as the bean name.

@scope (“prototype”) specifies the Scope of the Action as a prototype. We can use Scope =”prototype” to ensure that each request is handled by a separate Action. Avoid thread-safe actions in Struts. Spring’s default scope is a singleton (scope=”singleton”), which creates only one Action object. Each access is the same Action object. Data is not secure. Scope =”prototype” ensures that an Action object is created whenever a request is made.

3, @ Service

@service corresponds to a business layer Bean, for example:

@service ("userService") Public class UserServiceImpl implements userService {...... }Copy the code

The @service (“userService”) annotation tells Spring that when Spring creates an instance of UserServiceImpl, the bean name must be “userService”. When an Action needs to use an instance of UserServiceImpl, Spring can create a “userService” and inject it into the Action: To receive the spring-injected “userService”, declare a variable named “userService” in the Action as follows:

UserService @resource (name = "userService") private userService userService;Copy the code

Note: The type of the “userService” variable declared in the Action must be “UserServiceImpl” or its parent “userService”, otherwise it will not be injected due to type inconsistency. Since the declared “userService” variable in the Action is annotated with the @resource annotation and specifies its name = “userService”, this tells Spring that the Action is instantiating a “userService”, When Spring sees the @Resource annotation on the userService variable, it can tell from the name attribute that the Action needs an instance of UserServiceImpl. Spring will inject an instance of UserServiceImpl named “userService” into the Action variable “userService” to help the Action complete the userService instantiation. UserService UserService = new UserServiceImpl(); This is the most primitive way to instantiate userService. If you do not have Spring, you must pass the “UserService UserService = new UserServiceImpl();” command when an Action needs to use UserServiceImpl. The UserServiceImpl instance is created by Spring. The UserServiceImpl instance is created by Spring. Spring gives the created UserServiceImpl instance to the Action so that it can be used directly. Instead of actively creating a UserServiceImpl instance and being ready to use it, the Action is waiting for Spring to create a UserServiceImpl instance and inject it into the Action before it can use it. UserServiceImpl = UserServiceImpl; UserServiceImpl = UserServiceImpl; UserServiceImpl = UserServiceImpl; But now I can’t go to the new “UserServiceImpl” class instance, the new “UserServiceImpl” class instance has been taken away by Spring, only Spring can new “UserServiceImpl” class instance, The Action has to wait for Spring to create an instance of the “UserServiceImpl” class and then “beg” Spring to give him the instance so he can use the “UserServiceImpl” class. This is the core idea of Spring inversion of control, also known as “dependency injection”. “dependency injection” is also easy to understand. The Action needs to use UserServiceImpl to work, so it has a dependency on UserServiceImpl. Spring injects (i.e. “feeds”) the UserServiceImpl that Acion needs to rely on into the Action, which is known as “dependency injection.” If an Action depends on something, it asks Spring to inject it. If an Action needs something, Spring automatically infuses it.

4, @ the Repository

@repository corresponds to the data access layer Bean, for example:

@Repository(value="userDao")
public class UserDaoImpl extends BaseDaoImpl<User> {
………
}
Copy the code

The @repository (value=”userDao”) annotation tells Spring to create an instance of UserDaoImpl named “userDao”.

When the Service needs to use an instance of UserDaoImpl created by Spring named “userDao”, it can use the @resource (name = “userDao”) annotation to tell Spring, Spring simply injects the created userDao into the Service.

@resource (name = "userDao") private BaseDao<User> userDao;Copy the code

Summary of common Spring annotations

This article summarizes common Spring annotations for easy query and use, as follows:

Before using annotations, enable automatic scanning, where base-package indicates the package to be scanned (including sub-packages).

<context:component-scan base-package="cn.test"/> 
Copy the code

@Configuration treats a class as an IoC container, and if @Beans are registered in the head of one of its methods, they will be used as beans in the Spring container.

@scope Annotation Scope

@lazy (true) indicates delayed initialization

@service is used to annotate business layer components

@Controller is used to annotate control-layer components (such as actions in Struts)

@Repository is used to annotate data access components, known as DAO components.

@Component refers to a Component. This annotation is used when a Component is difficult to categorize.

@scope used to specify Scope (for classes)

@postconstruct is used to specify initialization methods (used on methods)

@predeStory used to specify the destruction method (used on methods)

DependsOn: Defines the order in which beans are initialized and destroyed

@primary: When there are multiple Bean candidates for autowiring, the Bean annotated as @primary will be the preferred, otherwise an exception will be thrown

@AutoWired is assembled by type by default, but if we wanted to use assembly by name, we could use it in conjunction with the @qualifier annotation.

As follows:

There are multiple instances of @autowired @Qualifier(“personDaoBean”) to work with

@resource is assembled by name by default, and by type when no bean matching the name can be found.

@postconstruct initializes annotations

@predestroy destroys annotations, defaults, singletons, load on startup

@async Asynchronous method invocation

The last

I have arranged a: Spring family barrel series, Java systematic information, (including Java core knowledge, interview topics and the latest Internet real questions in 20 years, e-books, etc.) friends who need to pay attention to the public number can be obtained.