Develop using annotations in spring

Foreword:

In Java, annotation is a special annotation that provides a metadata mechanism that can be used to describe information and instructions in the code and can be used by compilers, development tools, and runtime environments.

Commonly used annotations in the Spring framework include:

  1. @Controller: used to mark a class as a SpringMVC Controller object. The methods in the class marked by Controller are the corresponding actions.
  2. @Service: used to mark a class as a SpringMVC Service object, usually used for business logic layer processing.
  3. @Autowired: Used for automatic assembly. It can be marked on class member variables, methods and constructors to complete the work of automatic assembly.
  4. @RequestMapping: Used to map HTTP requests to the processing methods of MVC and REST controllers. It can be marked at the class level or method level.
  5. @Component: Represents a general annotation used to indicate that a class is a Spring container-managed class, but its use is now deprecated.
  6. @Scheduled: used for timer task annotations in Spring.

In addition, there are many other annotations, such as @Value, @Autowried, @Qualifier, @Resource, etc. used during bean injection.

Here is an introduction to the annotations used in this project

  1. @Configuration

    Function: Used to specify that the current class is a spring configuration class, and annotations will be loaded from this class when the container is created. When obtaining the container, you need to use AnnotationApplicationContext to obtain the class.class loaded with @Configuration annotation.

    /**
     * Spring configuration class, equivalent to bean.xml file
    */
    @Configuration
    public class SpringConfiguration { }

    Note: We have replaced the configuration file with classes, but how to configure the packages to be scanned when creating a container? Please see the next note.

  2. @ComponentScan

    Function: Used to specify the packages to be scanned by spring when initializing the container. The function is the same as in the spring xml configuration file:

    <context:component-scan base-package="com.fs"/>

    it’s the same

    @ComponentScan attribute:

    • basePackages/ value: used to specify the packages to be scanned

  3. @bean

    Function: This annotation can only be written on a method, indicating that an object is created using this method and placed in the spring container.

    Attribute: name: Specify a name (i.e. bean’s id) for the object created by the current @Bean annotation method.

1. Use idea to create a maven project

Directory Structure:

2. Add the following dependencies in the pom.xml file

<properties>
        <spring.version>5.2.15.RELEASE</spring.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--spring-test-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.10</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!--log4j-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.36</version>
        </dependency>
    </dependencies>

3. Add a properties file to output logs in resources

log4j.rootCategory=DEBUG, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n

4. Create a MyConfig class to be used as a configuration class

package com.jdfs.config;

import com.jdfs.mapper.UserMapper;
import com.jdfs.mapper.impl.UserMapperImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.jdfs")
public class MyConfig {

    @Bean("userMapper")
    public UserMapper getUserMapper(){
        return new UserMapperImpl();
    }
}

5. Create UserMapper class and interface

package com.jdfs.mapper;

public interface UserMapper {
    void insert();
    void delete();
}
package com.jdfs.mapper.impl;

import com.jdfs.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
public class UserMapperImpl implements UserMapper {
    @Override
    public void insert() {
        log.info("Save user successfully...");
    }

    @Override
    public void delete() {
        log.info("Delete user successfully...");
    }
}

6. Create the UserMapperService interface and implementation class

package com.jdfs.service;
public interface UserMapperService {
    void insert();
    void delete();
}
package com.jdfs.service.impl;

import com.jdfs.mapper.UserMapper;
import com.jdfs.service.UserMapperService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service("userMapperService")
public class UserMapperServiceImpl implements UserMapperService {
    @Autowired
    @Qualifier("userMapper")
    private UserMapper userMapper;
    @Override
    public void insert() {
        System.out.println("The business layer executes the insert method...");
        userMapper.insert();
    }

    @Override
    public void delete() {
        System.out.println("The business layer executes the delete method...");
        userMapper.delete();
    }
}

7. Write test classes

package com.jdfs.service;

import com.jdfs.config.MyConfig;
import com.jdfs.mapper.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.*;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MyConfig.class)
public class UserMapperServiceTest {

    @Autowired
    private UserMapperService userMapperService;
    @Test
    public void insert() {
        userMapperService.insert();
    }

    @Test
    public void delete() {
    }
}

8. Test results

Summary:

This blog is about some understanding of annotations when learning annotations in spring, and the implementation of a simple project. The advantage of developing based on annotations is that it does not require a lot of configuration, which also lays the foundation for future springboot learning. But based on annotations, it is difficult to integrate with other frameworks using only spring. Springboot should be able to solve this problem in the future.