SpringBook integrates Swagge, Quartz, Transactions, logback

Keywords: xml Spring SpringBoot Attribute

Swagger Integration
  • To automatically generate interface documents in a project, only some annotations are added to the controller and controller methods and entity classes to generate a complete interface document.
  • Adding dependencies
<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger2</artifactId>
			<version>2.8.0</version>
		</dependency>
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger-ui</artifactId>
			<version>2.8.0</version>
		</dependency>

  • Writing configuration classes
  • @ Enable Swagger 2 scan specifies Swagger annotations and generates interface documents
@Configuration
//Allow Swagger-provided annotations to be used in specified classes
//The container automatically scans the specified Swagger annotations and generates interface documents
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                // Specify the package where Controller will generate the interface document
                .apis(RequestHandlerSelectors.basePackage("com.sy.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                //Title of interface document
                .title("User Management System RESTful Interface Document")
                //Introduction to Interface Documents
                .description("This is an introduction to the interface documentation.")
                // Terms of Service Website
                .termsOfServiceUrl("http://blog.csdn.net/forezp")
                //Version number of interface
                .version("v1.0")
                // Licence
                .license("Soviet LP12345")
                //Contact Information: Company Name, Official Website Address, Mail Box for Contact
                .contact(new Contact("Shangyuan Education", "http://www.sy.com", "xxx@sy.com"))
                .build();
    }
}
  • Write controller, add annotations to the controller to explain the interface method and controller class.
  • @ Api annotation: equivalent to specifying a summary of the current controller in the interface document
  • @ ApiOperation Note: Explain the role of specific methods
    • value - parameter description
    • Notes - Other information notes
  • @ ApiParam() is used for methods, parameters, field descriptions; it represents the addition of metadata to parameters (description or whether it is necessary to fill in, etc.).
    • Name - parameter name (the real parameter name passed from the front end to the back end, not the formal parameter name of the method)
    • value - parameter description
    • required - Is it mandatory?
  • @ ApiIgnore prevents the current method from being written to the interface document
  • @ ApiModel's description of pojo types of stored parameters
    • value-name
    • Description-description
  • @ ApiModelProperty explains attribute fields in the pojio class
    • value-name
    • Name-attribute name
    • Example-example
@org.springframework.web.bind.annotation.RestController
@RequestMapping("/rest/v1.0")
//@ Api annotation: equivalent to specifying a summary of the current controller in the interface document
@Api(tags = "Modules for testing")
public class RestController {
    // Without specifying the request type, the interface generates seven different requests
    @RequestMapping(value = "user1", method = {RequestMethod.POST})
    //@ ApiOperation Note: Explain the role of specific methods
    @ApiOperation(value = "Getting User Information", notes = "Get user information based on user name and age")

    // @ ApiParam() is used for methods, parameters, field descriptions; it represents the addition of metadata to parameters (description or whether it is necessary to fill in, etc.).
    // Name - parameter name (the real parameter name passed from the front end to the back end, not the formal parameter name of the method)
    // value - parameter description
    // required - Is it mandatory?
    public Map<String, Object> user1(
            @ApiParam(value = "User name", name = "userName", required = true) @RequestParam String userName,
            @ApiParam(value = "Age", name = "age", required = true) @RequestParam int age) {

        Map<String, Object> map = new HashMap<>();
        map.put("userName", userName);
        map.put("age", 18);
        return map;
    }
    
Quartz Integrated Timing Task Scheduling Framework
  • Given a time expression, Quartz can perform an operation in a specified period of time or wait until a certain time to perform an operation.
  • Time expression: CRON expression
  • Introducing dependencies
        <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-quartz</artifactId>
            <version>2.0.9.RELEASE</version>
		</dependency>
  • Add configuration classes
@Configuration
public class QuartzConfig {
    @Bean
    public Scheduler scheduler() throws SchedulerException {
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        //Parameters in newJob: Task class
        JobDetail oneJob = JobBuilder.newJob(Task1.class).withIdentity("task1", "group1").build();
        TriggerBuilder<Trigger> newTrigger = trigger();
        newTrigger.withIdentity("trigger1", "group1");
        //The parameter in cronSchedule: cron expression, which specifies the execution time of a task
        newTrigger.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"));
        Trigger oneTrigger = newTrigger.build();
        scheduler.scheduleJob(oneJob, oneTrigger);
        scheduler.start();
        return scheduler;
    }

    @Bean
    public TriggerBuilder<Trigger> trigger() {

        return TriggerBuilder.newTrigger();
        }
    }
  • Adding specific task execution classes to implement Job interface
public class Task1 implements Job {
    /**
     * This method defines the specific process that tasks need to be executed.
     *
     * @param jobExecutionContext
     * @throws JobExecutionException
     */
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("Task execution...");
    }
}
Integration services
Annotated declarative transactions
  • Configure Data Source Transaction Manager
/**
 * Configure Data Source Transaction Manager
 */
@Bean
public PlatformTransactionManager txManager(DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}
  • Annotate the data source configuration class
    • Equivalent to tx:annotation-driven, transaction management can be done using @Transactional
    • @EnableTransactionManagement
  • To annotate the methods of management and manage things
    • @Transactional
Configuration through XML
  • Adding dependencies
        <dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
		</dependency>

  • Configure Data Source Transaction Manager
  • Configuration Notification Management
  • Configuration of tangent-to-tangent linkages
@Configuration
public class TransactionalConfig {
    // Transaction method timeout settings
    private static final int TX_METHOD_TIMEOUT = 5;
    // Tangent Point Expression of AOP Tangent
    private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.sy.service.*.*(..))";
    // Injection transaction manager
    @Autowired
    private PlatformTransactionManager transactionManager;

    @Bean
    public TransactionInterceptor txAdvice() {
        NameMatchTransactionAttributeSource txAttributeS = new NameMatchTransactionAttributeSource();
       //DML transaction
        RuleBasedTransactionAttribute requiredAttr = new RuleBasedTransactionAttribute();
        //Transaction Communication Behavior
        requiredAttr.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        //Transaction isolation level
        //requiredAttr.setIsolationLevel();
        //Transaction timeout
        requiredAttr.setTimeout(TX_METHOD_TIMEOUT);
        //What exceptions need to be rolled back
        requiredAttr.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));


        //DQL: Read-Only Transactions
        RuleBasedTransactionAttribute supportsAttr = new RuleBasedTransactionAttribute();
        supportsAttr.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
        //Is it read-only?
        supportsAttr.setReadOnly(true);


        Map<String, TransactionAttribute> txMethod = new HashMap<String, TransactionAttribute>();
        //DML transaction
        txMethod.put("save*", requiredAttr);
        txMethod.put("add*", requiredAttr);
        txMethod.put("insert*", requiredAttr);
        txMethod.put("update*", requiredAttr);
        txMethod.put("transfer*", requiredAttr);

        //DQL read-only transaction
        txMethod.put("find*", supportsAttr);
        txMethod.put("select*", supportsAttr);
        txMethod.put("get*", supportsAttr);
        txAttributeS.setNameMap(txMethod);

        TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager, txAttributeS);
        return txAdvice;
    }

    @Bean
    public Advisor txAdviceAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        //Tangent point
        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
        //Connect the tangent point with the cutter
        return new DefaultPointcutAdvisor(pointcut, txAdvice());
    }
}
logback log file
  • The SpringBook project states in the official documentation that the default has relied on some logging frameworks. And the recommended use is Logback.

  • SpringBoot already relies on Logback, so you don't need to add dependencies manually.

  • Spring Boot only supports log4j log configuration in versions 1.3.x and 1.3.x, and log4j2 and logback log configuration in versions 1.3.x and above.

  • The steps for LogBack to read configuration files

    • Try to find the file logback-test.xml under classpath
    • If the file does not exist, try to find logback.xml
    • If neither file exists, LogBack automatically minimizes its configuration with Basic Configuration, so that we can output the console log information without adding any configuration above.
  • Put xml files directly into resources

    • Common custom configurations
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
	<!--Define log file storage address not in LogBack Use relative paths in configuration -->
	<property name="LOG_HOME" value="/home" />
	<!-- console output -->
	<appender name="STDOUT"
		class="ch.qos.logback.core.ConsoleAppender">
		<encoder
			class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--Format output:%d Indicates the date.%thread Represents the thread name.%-5level: Level shows 5 character widths from left%msg: Log messages,%n Is a newline character -->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -
				%msg%n</pattern>
		</encoder>
	</appender>
	<!-- Generate log files per day -->
	<appender name="FILE"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<rollingPolicy
			class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!--File name of log file output -->
			<FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log
			</FileNamePattern>
			<!--Days of log file retention -->
			<MaxHistory>30</MaxHistory>
		</rollingPolicy>
		<encoder
			class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--Format output:%d Indicates the date.%thread Represents the thread name.%-5level: Level shows 5 character widths from left%msg: Log messages,%n Is a newline character -->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -
				%msg%n</pattern>
		</encoder>
		<!--Maximum size of log files -->
		<triggeringPolicy
			class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
			<MaxFileSize>10MB</MaxFileSize>
		</triggeringPolicy>
	</appender>

	<!-- Log output level -->
	<root level="INFO">
		<appender-ref ref="STDOUT" />
	</root>
</configuration>
  • If you want to print the SQL statement from mybatis output
    • logging.level.com.sy.mapper=debug
Other annotations in pringBook
@Profile
  • In order to enable SpringBoot applications to switch flexibly in different environments
    • development environment
    • testing environment
    • production environment
  • @ Profile annotations allow you to configure the same parameters in SpringBook applications in different environments
    Specify which environment configuration information to use by activation
  • (1) Usage 1
  • Prepare different application iton - environment names.
  • Specify different configurations of the same parameters in different properties files
  • Finally, in application.properties, the configuration information in which environment to activate is specified by spring. profiles. activity
    • If the same configuration item is specified in the activated environment as in application.properties
    • The configuration in the activation environment overrides the configuration in application.properties
    • Syntax: spring.profiles.active=dev
  • (2) Usage II
  • Add Profile annotations directly to a specific configuration class
  • For SpringBook applications where only certain beans need to specify a specific environment, you can add the @Profile annotation directly to the configuration class
@PropertySource

Read the specified properties configuration file and inject the values into the class as attributes

  • Write a properties configuration file
  • You need to read the configuration file in the class through the @PropertySource annotation (which can be written on the startup class or in other classes)
    • @PropertySource({"classpath:app.properties"})
  • spEL injection through @Value annotation
    • @Value("${app.param1}")
@ImportResource
  • Introducing Spring configuration file, SpringBoot advocates 0 configuration file, but some frameworks have to be configurated through XML configuration to get more simple configuration using XML, so sometimes XML files are introduced.
Conditional annotations
  • Some objects are instantiated automatically after introducing some dependencies or adding some configuration information (the creation of objects needs to satisfy certain conditions). In this case, the condition annotations provided in SpringBook can be used to complete the process.
  • Define conditional classes to implement the Condition interface
public class User1Condition implements Condition {

    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        //The return value of the method determines whether the current condition holds.
        //Bean objects can be retrieved from containers
        //conditionContext.getBeanFactory().getBean()

        //Get configuration parameters for the environment
        //conditionContext.getEnvironment().getProperty(key);

        return true;
    }
}

  • Specify instantiation conditions for the current bean where @Bean exposes the bean object
    • @Conditional(User1Condition.class)

Posted by bulrush on Thu, 25 Jul 2019 23:58:55 -0700