SSM SpringIoc(下)

十二、注解

1、注解理解

    和 XML 配置文件一样,注解本身并不能执行,仅仅只是做一个标记,具体的功能是框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作

    本质上:所有一切的操作都是 Java 代码来完成的,XML 和注解只是告诉框架中的 Java 代码如何执行。

2. 扫描理解

    Spring 为了知道程序员在哪些地方标记了什么注解,就需要通过扫描的方式,来进行检测。然后根据注解进行后续操作。

3.注解展示

SSM SpringIoc(下)_第1张图片

 

扫描范围的三种指定方式:



    

   



    

        

    

   



    



        

    

4.BeanName问题

在我们使用 XML 方式管理 bean 的时候,每个 bean 都有一个唯一标识——id 属性的值,便于在其他地方引用。现在使用注解后,每个组件仍然应该有一个唯一标识。

默认情况:

类名首字母小写就是 bean 的 id。例如:SoldierController 类对应的 bean 的 id 就是 soldierController。

情况1:可以使用注解的value指定BeanName

@Controller(value = "tianDog")

public class SoldierController {

}

补充:注解中只设置一个属性时,value可以省略。(常用)

@Service("smallDog")

public class SoldierService {

}

总结:

    1. 注解方式IoC只是标记哪些类要被Spring管理

    2. 最终,我们还需要XML方式或者后面讲解Java配置类方式指定注解生效的包

    3. 现阶段配置方式为 注解 (标记)+ XML(扫描)

十三、Bean的注解

1、周期方法

在标题九中已经讲过xml方式配置调用方法,是在xml文件中指定bean组件并且填写init-method和destroy-method的属性。

周期方法也能使用注解,举例如下:

public class BeanOne {

  @PostConstruct  //注解制指定初始化方法

  public void init() {

    // 初始化逻辑

  }

}

 

public class BeanTwo {

  @PreDestroy //注解指定销毁方法

  public void cleanup() {

    // 释放资源逻辑

  }

}

  周期方法要求: 方法命名随意,但是要求方法必须是 public void 无形参列表

 

十四、DI装配的注解:@Autowired+Qualifier、@Resource与@Value

1. 自动装配:@Autowired

    (1)要求

        参与自动装配的组件(需要装配、被装配)全部都必须在IoC容器中。

        注意:不区分IoC的方式!XML和注解都可以!

        在成员变量上直接标记@Autowired注解即可,不需要提供setXxx()方法。以后我们在项目中的正式用法就是这样。

@Autowired

@Qualifier(value = "UserServiceImpl")

//@Qualifier必须配合Autowired使用

private UserService userService;

//自动装配注解(DI)

//@Autowired默认情况下至少要求有一个bean

//不推荐使用佛系装配,会报空指针异常



@Resource(name = "userServiceImpl1")//@Resource相当于@Autowired+@Qualifier(value = "UserServiceImpl")

 

@Resource注解默认根据Bean名称装配,未指定name时,使用属性名作为name。通过name找不到的话会自动启动通过类型装配。

@Autowired注解默认根据类型装配,如果想根据名称装配,需要配合@Qualifier注解一起用。

 @Resource注解用在属性上、setter方法上。

 @Autowired注解用在属性上、setter方法上、构造方法上、构造方法参数上。

因为@Resource注解来自JDK而不是spring自身就有的包,需要引入资源。

@Controller

public class XxxController {

    /**

     * 1. 如果没有指定name,先根据属性名查找IoC中组件xxxService

     * 2. 如果没有指定name,并且属性名没有对应的组件,会根据属性类型查找

     * 3. 可以指定name名称查找!  @Resource(name='test') == @Autowired + @Qualifier(value='test')

     */

    @Resource

    private XxxService xxxService;

 

    //@Resource(name = "指定beanName")

    //private XxxService xxxService;

 

    public void show(){

        System.out.println("XxxController.show");

        xxxService.show();

    }

}

 

 标记位置

      1)成员变量

            这是最主要的使用方式,与xml进行bean ref引用不同,他不需要有set方法

 ``

`Java

@Service("smallDog")

public class SoldierService {

   

    @Autowired

    private SoldierDao soldierDao;

   

    public void getMessage() {

        soldierDao.getMessage();

    }

}

```

       2) 构造器

```

Java

@Controller(value = "tianDog")

public class SoldierController {

   

    private SoldierService soldierService;

   

    @Autowired

    public SoldierController(SoldierService soldierService) {

        this.soldierService = soldierService;

    }

    ……

```

        3. setXxx()方法

```

Java

@Controller(value = "tianDog")

public class SoldierController {

 

    private SoldierService soldierService;

 

    @Autowired

    public void setSoldierService(SoldierService soldierService) {

        this.soldierService = soldierService;

    }

    ……

```

      工作流程

SSM SpringIoc(下)_第2张图片

        - 首先根据所需要的组件类型到 IOC 容器中查找

            - 能够找到唯一的 bean:直接执行装配

            - 如果完全找不到匹配这个类型的 bean:装配失败

            - 和所需类型匹配的 bean 不止一个

                - 没有 @Qualifier 注解:根据 @Autowired 标记位置成员变量的变量名作为 bean id 进行匹配

                    - 能够找到:执行装配

                    - 找不到:装配失败

                - 使用 @Qualifier 注解:根据 @Qualifier 注解中指定的名称作为 bean id进行匹配

                    - 能够找到:执行装配

                    - 找不到:装配失败

```Java

@Controller(value = "tianDog")

public class SoldierController {

   

    @Autowired

    @Qualifier(value = "maomiService222")

    // 根据面向接口编程思想,使用接口类型引入Service组件

    private ISoldierService soldierService;

```

 佛系装配(required=false)

    给 @Autowired 注解设置 required = false 属性表示:能装就装,装不上就不装。但是实际开发时,基本上所有需要装配组件的地方都是必须装配的,用不上这个属性

 

```Java

@Controller(value = "tianDog")

public class SoldierController {

 

    // 给@Autowired注解设置required = false属性表示:能装就装,装不上就不装

    @Autowired(required = false)

    private ISoldierService soldierService;

```

2、@Resource

相当于@Autowierd+@Qualifier

@Resource(name = "userServiceImpl1")//@Resource相当于@Autowired+@Qualifier(value = "UserServiceImpl")

 

3、@value的使用

@Value 通常用于注入外部化属性

例如:组件类中:

@Component

public class JavaBean {

    private String name="Qum";

    private int age;

    @Value("${jdbc.username:admin}")

    private String username;

    @Value("${jdbc.password:admin}")

    private String password;

    //1、可以直接赋值

    //2、注解赋值  使用@Value注解,但该注解一般不用来给属性赋值

    //@value属性一般用于读取jdbc中的配置,可以通过在xml文件中引入jdbc文件(主要使用context标签),可以在java文件中实现对jdbc中的值的读取

}

 

补充:

情况1: ${key} 取外部配置key对应的值!

 情况2: ${key:defaultValue} 没有key,可以给与默认值

xml文件中对jdbc.properties的外部配置文件进行引入。先指定扫描的包的位置,再使用location指定文件名



小结:注解+XML IoC方式问题总结

    1. 自定义类可以使用注解方式,但是第三方依赖的类依然使用XML方式!

    2. XML格式解析效率低!

十五、完全注解

第一步:创建config包下的配置类java文件:@Configuration,@PropertySource,@ComponentScan

使用@Configuration注解声明该文件是配置类文件。

 

@ComponentScan({"com.atguigu.ioc_01","com.atguigu.ioc_02"})//多个包的写法

@PropertySource(value = "classpath:jdbc.properties")//代替xml文件中引入jdbc文件的context标签

@Configuration

//声明为配置类文件

public class JavaConfiguration {

 

}

第二步:创建java文件,创建ioc容器,获取bean组件

通过AnnotationConfigApplicationContext方法创建ioc容器,通过ioc容器获取bean组件。

 

public class SpringIocTest {

    @Test

    public void test(){

        //两种获取ioc容器的方式

        //1

        ApplicationContext applicationContext=

                new AnnotationConfigApplicationContext(JavaConfiguration.class);

 

        //2

        AnnotationConfigApplicationContext annotationConfigApplicationContext1=

        new AnnotationConfigApplicationContext();

        annotationConfigApplicationContext1.register(JavaConfiguration.class);

        annotationConfigApplicationContext1.refresh();

//要记得调用refesh方法!

 

        //获取bean

        StudentController bean =

                (StudentController) applicationContext.getBean("StudentController.class");

    }

}

 

十六、@Bean

 

@Configuration

public class JavaConfiguration {

    //xml中一个bean标签在java配置类文件中对应一个方法,方法的返回值类型=bean组件的类型和接口和父类

    // 方法的名字=bean id

    //方法体可以自定义实现过程即可

    //最重要的一步:加上@bean注解  真正让配置类的方法创建的组件存储到ioc容器

 

    @Value("{&atguigu.username}")

    private String username;

    @Value("{&atguigu.url}")

    private String url;

    @Value("{$atguigu.password}")

    private String password;

    @Value("{&atguigu.driver}")

    private String driver;

 

    @Bean

    public DruidDataSource dataSource(){

        //实现具体的实例化过程

        DruidDataSource dataSource=new DruidDataSource();

        dataSource.setUrl(url);

        dataSource.setPassword(password);

        dataSource.setUsername(username);

        dataSource.setDriverClassName(driver);

 

        return dataSource;

    }

}

1、方法名

不指定时beanName默认方法名,可以在注解后指定名称

@Configuration

public class AppConfig {

 

  @Bean("myThing") //指定名称

  public Thing thing() {

    return new Thing();

  }

}

2、周期方法

也可以在bean注解中进行配置

@Bean(name = "Qum",initMethod = "init",destroyMethod = "")

3、作用域

使用@Scope的注解

@Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON)

4、bean组件中需要其他组件的方法

@Bean(name="Dit")

public JdbcTemplate JdbcTemplate(){

    JdbcTemplate jdbcTemplate=new JdbcTemplate();

    //需要ioc容器中的其他组件

    //其他组件也是@bean方法,可以直接调用

    jdbcTemplate.setDataSource(dataSource());

    //不推荐

    return jdbcTemplate;

}

 

@Bean

public JdbcTemplate JdbcTemplate1(DataSource Qum,DataSource Dit){

    JdbcTemplate jdbcTemplate=new JdbcTemplate();

    //需要ioc容器中的其他组件

    //其他组件也是@bean方法,可以直接调用

    //方案2:形参列表声明想要的组件类型,可以是有一个也可以是多个,ioc容器也会注入

    //要求必须有对应类型的组件,如果没有,则抛出异常。

    //如果有多个  输入参数时  输入对应的beanId

    jdbcTemplate.setDataSource(Qum);

    return jdbcTemplate;

5、@import组件

可以进行ioc配置的简化,导入其他配置类

@Import(value = {JavaConfigurationB.class})

//导入的也必须是一个配置类

此时,ioc容器中只需要传入javaConfigurationA的.class

@Test

public void test1(){

ApplicationContext applicationContext=

        new AnnotationConfigApplicationContext(JavaConfigurationA.class);

}

6.Test测试环境导入依赖



    org.junit.jupiter

    junit-jupiter-api

    5.3.1





    org.springframework

    spring-test

    6.0.6

    test

你可能感兴趣的:(SSM,java,开发语言)