1. 注解方式

使用XML方式管理Bean以及Bean的依赖,非常直观,但是配置相对繁琐一些,尤其是当Bean多了之后,有没有更简便的方式呢?

Annotation配置

使用注解的方式,可以极大的简化配置。

1.1 Bean的定义

@Component注解,就相当于定义了一个Bean,Bean的名称默认是所在类的类名,首字母小写

@Component
public class MailService {}
1
2
@Component
public class UserService {}
1
2

1.2 Bean的注入

@Autowired就相当于把指定类型的Bean注入到指定的字段中。

@Autowired大幅简化了注入,因为它不但可以写在set()方法上,还可以直接写在字段上,甚至可以写在构造方法中。

 @Autowired
    private MailService mailService;
1
2
 @Autowired
    public void setMailService(MailService mailService) {
        this.mailService = mailService;
    }
1
2
3
4
 public UserService(@Autowired MailService mailService){
        this.mailService = mailService;
    }
1
2
3
  @Autowired
    public UserService(MailService mailService){
        this.mailService = mailService;
    }
1
2
3
4

1.3 使用

1.3.1 注解+xml混合使用

xml配置中 加入扫包路径,这样启动的时候,spring就会去对应的包下去扫描对应的注解

<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

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

</beans>
1
2
3
4
5
6
7
8
9
10

按照之前的方式 启动测试即可:

package com.mszlu;

import com.mszlu.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.registerUser("ddd@mszlu.com","123456","ddd");
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

1.3.2 纯注解使用

定义Spring的配置类

package com.mszlu.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.mszlu")
public class SpringConfig {
}

1
2
3
4
5
6
7
8
9
10

启动类

package com.mszlu;

import com.mszlu.config.SpringConfig;
import com.mszlu.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

    public static void main(String[] args) {
//        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = (UserService) context.getBean("userService");
        userService.registerUser("ddd@mszlu.com","123456","ddd");
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

说明:@Configuration 指名SpringConfig为Spring的配置类,是AnnotationConfigApplicationContext必须传入一个标注了@Configuration的类名

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
//其实@Configuration注解就是@Component,只是为了语义的表达
public @interface Configuration {}
1
2
3
4
5
6

2. Bean定义的其他注解

2.1 @Controller

controller层主要负责具体的业务模块流程的控制,通常调用Service层的接口来控制业务流程,又被称为WEB层,API层等,一般负责接收参数,解析参数,调用业务逻辑层代码,将数据返回给前端等

@Controller注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
//本质上还是@Component,用于标识Controller层
public @interface Controller {}
1
2
3
4
5
6

2.2 @Service

service层主要负责业务模块的应用逻辑应用设计,涉及到数据库的访问,调用dao层来实现

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
//本质上还是@Component,用于标识Service层
public @interface Service {}
1
2
3
4
5
6

2.3 @Repository

dao层主要做数据持久层的工作,负责与数据库进行交互

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
//本质上还是@Component,用于标识dao层
//一般用不到,因为我们一般使用Mybatis,使用@Mapper注解来标识dao的接口
public @interface Repository {}
1
2
3
4
5
6
7

2.4 @Bean

一般在使用第三方Bean的时候,比如数据库连接池HikariDataSource

<!-- https://mvnrepository.com/artifact/com.zaxxer/HikariCP -->
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>3.4.1</version>
</dependency>

1
2
3
4
5
6
7
//源码中 也并没有类似@Component的注解,那么我们如何使用注解,将它交给我们得Spring容器管理呢?
public class HikariDataSource extends HikariConfig implements DataSource, Closeable
{}
1
2
3

用@Bean这个注解,用于定义第三方的Bean,将其交给Spring容器统一管理。

package com.mszlu.config;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//不要忘记@Configuration ,@Bean注解生效的前提是JdbcConfig首先是受Spring容器管理的
//也就是说 Spring在扫描的时候,先扫描类,后扫描类中的方法
@Configuration
public class JdbcConfig {

    @Bean
    public HikariDataSource dataSource(){
        HikariConfig configuration = new HikariConfig();
        configuration.setDriverClassName("com.mysql.jdbc.Driver");
        configuration.setJdbcUrl("jdbc:mysql://localhost:3306/spring_db?useUnicode=true&amp;characterEncoding=utf8");
        configuration.setUsername("root");
        configuration.setPassword("root");
        HikariDataSource hikariDataSource = new HikariDataSource(configuration);
        return hikariDataSource;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23