Spring学习笔记【part04】IoC注解开发

导读:本篇文章讲解 Spring学习笔记【part04】IoC注解开发,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

Spring 学习笔记 Part04

1. 基于注解的 IoC 配置

​ 注解配置和 xml 配置要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。

<!-- beans.xml配置 -->
基于注解整合时,导入约束时需要多导入一个 context 名称空间下的约束。
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:context="http://www.springframework.org/schema/context"
 	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	   xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context.xsd">
    
    告知 spring 创建容器时要扫描的包 
    <context:component-scan base-package="com.itheima"/>
    
</beans>

2. 注解基本标签介绍

2.1 用于创建对象的

​ 他们的作用就和在XML配置文件中编写一个 标签实现的功能是一样的。


@Component //用于把当前类对象存入spring容器中
    
属性:
	value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。

@Controller //一般用在表现层

@Service //一般用在业务层

@Repository //一般用在持久层

属性:
	value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。

以上三个注解他们的作用和属性与Component是一模一样。
他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰(作为@Component的语义化别名仅此而已)。

2.2 用于注入数据的

​ 他们的作用就和在XML配置文件中编写一个 标签或者标签实现的功能是一样的。

<!-- bean类型的注解注入 -->
    
@Autowired //自动按照类型注入 (一开始不匹配beanid,而是直接匹配类型,类型匹配不成功则用变量名称去匹配beanid)
	出现位置:
    	可以是变量上,也可以是方法上。
	只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功。如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。
    在使用注解注入时,set方法就不是必须的了。
 

@Qualifier //在按照类中注入的基础之上再按照名称注入 (使用注解的value值直接匹配beanid)
    如果Ioc容器中有多个类型匹配时使用
    出现位置:
        在给类成员注入时不能单独使用,必须配合@Autowired。
        在给方法参数注入时可以单独使用。
属性:
	value:用于指定注入bean的id。
        
        
@Resource //直接按照bean的id注入
    其效果等于@Autowired配合@Qualifier。
    它可以独立使用。
属性:
	name:用于指定bean的id。
        
        
以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现     

<!-- 基本数据类型和String类型的注解注入 -->
    
@Value //用于注入基本类型和String类型的数据
属性:
	value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式)
SpEL的写法:${表达式}

<!-- 集合类型的注解注入 -->
    
集合类型的注入只能通过XML来实现

2.3 用于改变作用范围的

​ 他们的作用就和在bean标签 中使用scope属性实现的功能是一样的。


@Scope //用于指定bean的作用范围

	只能作用在类上。
        
属性:
	value:指定范围的取值。常用取值:singleton、prototype、request、session、globalsession 

2.4 和生命周期相关的

​ 他们的作用就和在bean标签中使用init-method和destroy-method的作用是一样的。


@PostConstruct //用于指定初始化方法

@PreDestroy //用于指定销毁方法

3. 注解新标签介绍

​ 创建一个配置类,它的作用和bean.xml是一样的。


@Configuration //指定当前类是一个配置类
	当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写。

    
@ComponentScans //包含@ComponentScan数组
@ComponentScan //用于通过注解指定spring在创建容器时要扫描的包
	我们使用此注解就等同于在xml中配置了:<context:component-scan base-package="com.itheima"/>
属性:
	value、basePackages:它们作用是一样的,都是用于指定创建容器时要扫描的包。
    

@Bean //用于把当前方法的返回值作为bean对象存入spring的容器中IoC容器中
	当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象。(查找的方式和Autowired注解查找的方式是一样的) 
属性:
	name:用于指定bean的id。当不写时,默认值是当前方法的名称
        
        
@Import //用于导入其他的配置类
当我们使用Import的注解之后,有Import注解的类就父配置类,而导入的都是子配置类。        
属性:
	value:用于指定其他配置类的字节码。

        
@PropertySource //用于指定properties文件的位置
属性:
 	value:指定文件的名称和路径。
		关键字:classpath,表示类路径下
        
  
上节补充:
@Qualifier //贴在方法参数上时可单独出现,类成员时则需配合Autowire
属性:
	value:指定要注入参数的beanid
        

创建基于注解配置的IoC容器的实现类:

​ AnnotationApplicationContext ( )

​ 构造方法参数: 有 @Configuration 注解的类.class(用于指定配置类的字节码)

实例

//配置文件主类
@Configuration
@ComponentScan("com.itheima")
@Import(JdbcConfig.class)
@PropertySource("classpath:jdbcConfig.properties")
public class SpringConfiguration {

}
//和spring连接数据库相关的jdbc配置子类
@Configuration
@ComponentScan("com.itheima")
@Import(otherConfig.class)
@PropertySource("classpath:jdbcConfig.properties")
public class JdbcConfig {

    @Value("${jdbc.driver}")
    private String driver;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    /* 用于创建一个QueryRunner对象 */
    @Bean(name="runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(@Qualifier("ds2") DataSource dataSource){
        return new QueryRunner(dataSource);
    }

    /* 创建数据源对象 */
    @Bean(name="ds2")
    public DataSource createDataSource(){
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass(driver);
            ds.setJdbcUrl(url);
            ds.setUser(username);
            ds.setPassword(password);
            return ds;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    @Bean(name="ds1")
    public DataSource createDataSource1(){
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass(driver);
            ds.setJdbcUrl("jdbc:mysql://localhost:3306/eesy02");
            ds.setUser(username);
            ds.setPassword(password);
            return ds;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
}

补充个内容,当xml引入外部config.properties时,使用的标签是< context:property-placeholder >

<context:property-placeholder location="classpath:jdbcConfig.properties"/>

<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
</bean>

4. Spring 注解整合 Junit

​ 每个测试方法都有两行取IoC容器的代码:

ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
AccountService as = ac.getBean("accountService",AccountService.class);

​ 如果不写的话,直接会提示空指针异常。junit不能为我们创建spring容器,因为它不知晓我们是否使用了spring框架,但junit给我们暴露了一个注解,让我们可以替换掉它的运行器。

Spring 整合 junit 步骤:

第 1 步:导入 spring 整合 junit 的 jar 坐标 —— spring-test 。

第 2 步:使用 junit 提供的一个注解 @Runwtih 把原有的main方法替换掉,替换成spring提供的。

第 3 步:用注解 @ContextConfiguration 告知 spring 的运行器,spring 和 IoC 创建时基于xml还是注解的,并且说明位置。

​ 属性:

​ locations:指定xml文件的位置,加上classpath关键字,表示在类路径下。

​ classes:指定注解类所在的位置,返回值为 .class 字节码类型

第 4 步:使用 @Autowired 给测试类中的变量注入数据

//spring × junit 实例
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"classpath:bean.xml"})
public class AccountServiceTest {
    
    @Autowired
	private IAccountService as ;
    
    @Test
    methods...
}

注意:当我们使用 spring 5.x 版本时,要求 junit 的 jar必须是4.12及以上。

5. Spring 注解和 XML 的选择问题

注解的优势:

​ 配置简单,维护方便(我们找到类,就相当于找到了对应的配置)。

XML的优势:

​ 修改时,不用改源码。不涉及重新编译和部署。

两种方式的比较:

在这里插入图片描述

总结:

企业没有要求的情况下,XML和注解混用是最合适的。

​ 自己写的类用注解配置更方便;

​ jar包中的类用XML配置更方便。

拓展:为什么不把测试类配置到xml中呢?

首先一个问题,配到 XML 中能不能用呢?

​ 答案是肯定的,没问题,可以使用,但是没必要。

其次,为什么不采用xml配置方式呢?

​ 第一:当我们在 xml 中配置了一个 bean,spring 加载配置文件创建容器时,就会创建对象。

​ 第二:测试类只是我们在测试功能时使用,而在项目中它并不参与程序逻辑,也不会解决需求上的问题,所以创建完了,并没有使用。那么存在容器中就会造成资源的浪费。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84501.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!