JavaWeb笔记(25)-spring框架深入

  1. spring基于注解的IOC配置
1. 注解分类:
    初始的xml配置:
    <bean id="" class="" scope="" init-method="" destroy-method="">
        <property name="" vaule="" | ref=""></property>
    </bean>
    a. 用于创建对象
        其作用与xml配置中编写一个<bean>标签作用一样
    b. 用于注入数据
        其作用与xml配置中的<bean>标签内编写一个<property>标签作用一样
    c. 用于改变作用范围
        其作用与xml配置的<bean>标签中使用scop属性实现的功能是一样的
    d. 生命周期相关
        其作用与xml配置的<bean>标签中使用init-method/destroy-method属性实现的功能是一样的
2. 使用spring基于注解的IOC配置:
    a. 导入相关jar包
        spring-aop-5.0.2.RELEASE.jar        --      基于注解开发的必备jar包
        spring-beans-5.0.2.RELEASE.jar      --      中间4个为核心容器的jar包
        spring-context-5.0.2.RELEASE.jar
        spring-core-5.0.2.RELEASE.jar
        spring-expressoin-5.0.2.RELEASE.jar
        spring-jcl-5.0.2.RELEASE.jar        --      集成了apache的日志组件做成了自己的jar包
    b. 创建配置文件,添加约束,标识使用注解开发而非xml文档
        /resource/anno_bean.xml
        <?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
                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标签-->
            <context:componet-scan base-package="cn.mysilent"></context:componet-scan>
        </beans>
3. 用于创建对象的注解:
    a. @Component1. 用于将当前类对象加入到核心容器中
        2. 属性:
            value:用于指定该bean的id。不写时,默认id为首字母小写的类名
    b. @Controller1.@Component功能与属性一致
        2. 一般用于表现层
    c. @Service1.@Component功能与属性一致
        2. 一般用于业务层
    d. @Repository1.@Component功能与属性一致
        2. 一般用于持久层
    @Controller/@Service/@Repository三个注解功能都和Component一致,只是为了更加清晰的指明该对象用于哪一层
    对于不属于三层架构的对象使用Component注解就好
4. 用于注入参数的注解:
    a. @Autowired1. 自动按照类型注入。
            只要核心容器中有唯一一个bean对象类型与待注入的变量类型一致就能成功注入,否则报错
            类型的比较过程直接跳过key,比较容器中value值的类型
        2. 出现位置:变量定义上,方法上
        3. 使用注解注入时,成员变量的set方法不再必须
        4. 如果核心容器中有多个bean对象类型与待注入变量类型一致时
            spring会将变量名作为key值在容器中进行查找,如果找到一致的,则注入该key对应的value值类型的对象
            当没有匹配的key值在容器map中时,程序报错
    b. @Qualifier1. 在按照类型注入的基础上再按照名称注入。优化了Autowired注解的功能
            但是它在给类成员注入时不能单独使用
            只在给方法参数注入时可以单独使用
        2. 属性:
            value:用于指定注入的bean类型的id
        3. 当对变量使用时,必须在变量上加上@Autowired注解,二者搭配使用
    c. @Resource1. 直接按照bean的id注入,它可以单独使用
        2. 属性:
            name:用于指定注入的bean类型的id
    d. @Value1. 专门用于注入基本属性和String类型。
            @Autowired/@Qualifier/@Resource不能注入基本数据类型和String类型
        2. 属性:
            value:用于指定数据的值。该值可以使用spring中的SpEL(spring中的EL表达式)
                    形式:${表达式} -- EL表达式写在jsp中,则为jsp的EL表达式,从4个域中获取数据
                                    -- EL表达式写在spring的注解/配置文件中,则为SpEL,从spring指定位置获取数据
                                    -- EL表达式写在mybatis的注解/配置文件中,则从mybatis指定位置获取数据
5. 用户改变作用范围的注解:
    a. @Scop1. 用于指定bean的作用范围
        2. 属性:
            value:用于指定bean对象的作用范围。常用singleton(默认)/prototype
6. 与生命周期相关:
    a. @PostConstruct
        1. 标识在方法上,标识该方法为bean对象初始化方法
    b. @PreDestroy1. 标识在方法上,标识该方法为bean对象的销毁方法
  1. spring中新注解:用于消除仍然存在的xml配置文件
1. 以上介绍的注解只能标注在自定义的类上,而jar包中定义的类不能使用
    使得在使用注解时,如QueryRunner等jar包中定义的类仍然需要配置在xml文档中
    于是spring中允许自定义一个类,该类用作xml配置文件的功能
2. 新注解:
    a. @Configuration1. 指定当前类是一个配置类
        2. 当配置类作为AnnotationConfigApplicationContext创建ApplicationContext对象的参数时,可以省略(不建议)
    b. @ComponentScan1. 用于通过注解指定spring创建容器时需要扫描的包
        2. 属性:
            basePackage(value):指定创建容器时扫描的包
            @ComponentScan(basePackage={"xxx"})效果等同于:
            <context:componet-scan base-package="xxx"></context:componet-scan>
    c. @Bean:
        1. 用于将当前方法的返回值作为bean对象存入spring的IOC容器
        2. 属性:
            name:指定存入容器时的key。不写时使用默认值,为该方法的方法名
    d. @Import1. 用于导入其他的注解类,将各个小的配置类import到一个大的配置类中,此时参数仅传递大配置类.class即可
            不再需要传递多个配置类.class
        2. 属性:
            value:用于指定其他配置类的字节码文件。
    e. @PropertySource/@PropertySources1. 用于指定properties配置文件的位置
        2. 属性:
            value:指定配置文件的名称和路径
                   使用关键字classpath,表示类路径下。如@PropertySource("classpath:jdbc.properties")
3. 如果使用注解配置方法时,如果方法有参数,spring框架会去查找容器中是否有可用的bean对象
    查找方式与@Autowired注入方式一样
4. 原始注解配置的xml文档:消除了自定义类的bean标签配置
    /resource/anno_bean.xml
    <?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
                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标签-->
            <context:componet-scan base-package="cn.mysilent"></context:componet-scan>
            
            <!--配置QueryRunner,为了使每个查询不相互干扰,配置该对象的创建为多例prototype-->
            <!--如果QueryRunner是单例对象,则面临多个dao使用时,可能引发线程安全问题-->
            <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
                <!--注入数据源-->
                <constructor-arg name="ds" ref="dataSource"></constructor-arg>
            </bean>
        
            <!-- 配置数据源 -->
            <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
                <!--连接数据库的必备信息-->
                <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
                <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
                <property name="user" value="用户名"></property>
                <property name="password" value="密码"></property>
        </beans>
5. 使用自定义注解类来代替anno_bean.xml文档:
    /config/SpringConfiguration.java
    @Configuration
    @ComponentScan("cn.mysilent")
    public class SpringConfiguration {
        //创建一个QueryRunner对象并放入容器中
        @Bean(name="runner")
        @Scop("prototype")
        public QueryRunner createQueryRunner(DataSource dataSource){
            return new QueryRunner(dataSource);
        }
        
        //创建一个DataSource对象并放入容器
        @Bean(name="dataSource")
        public DataSource createDataSource(){
            try{
                ComboPoolDataSource ds = new ComboPoolDataSource();
                ds.setDriverClass("com.mysql.jdbc.Driver");
                ds.setJdbcUrl("jdbc:mysql://localhost:3306/test");
                ds.setUser("root");
                ds.setPassword("12345");
            }
        }
    }
    注意:
        我们在xml配置文件中,为了保证线程安全问题,将QueryRunner对象的产生设置为多例对象
        因此在,QueryRunner对象的创建上加上@Scop注解
6. 使用properties配置文件动态更新配置类:
    /resource/jdbc.properties
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/test
    jdbc.username=root
    jdbc.password=1234
    
    /config/JdbcConfiguration.java
    /**
     * 和spring连接数据库相关的配置类
     * 使用SpEL表达式动态获取配置文件中的值
     */
    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;

        @Bean(name="runner")
        @Scope("prototype")
        public QueryRunner createQueryRunner(@Qualifier("ds2") DataSource dataSource){
            //当容器中含有多个符合注入的bean对象时,使用@Qualifier注解直接给参数指定注入的bean对象
            //@Qualifier注解于成员变量不能直接使用,但是对于方法的参数可以单独使用
            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/test02");
                ds.setUser(username);
                ds.setPassword(password);
                return ds;
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    }
    
    /**
    *该配置类为父配置类,其他子配置类导入到该类中,使用PropertySource配置properties文件路径
    */
    @Configuration
    @ComponentScan("com.itheima")
    @Import(JdbcConfig.class)
    @PropertySource("classpath:jdbcConfig.properties")
    public class SpringConfiguration {
        //...
    }
7. 使用AnnotationConfigApplicationContext创建核心容器:
    ApplicationContext coreObj = new AnnotationConfigApplicationContext(Configuration注解类.class);
8. 原则:结合使用
    自定义的类建议使用注解
    jar包中已有的类建议用xml配置
  1. spring整合Junit单元测试
1. 使用步骤:
    a. 导入相关jar包:
        spring-test-5.0.2.RELEASE.jar
    b. 使用Junit提供的注解将原有的main方法替换为spring提供的能够生成容器的main方法
        注解:@RunWith
        属性:
            指定替换的main方法所在类的字节码文件
        @RunWith(SpringJunit4ClassRunner.class)
        public class AccountServiceTest{
            //单元测试代码
        }
    c. 告知spring的运行器,spring的IOC创建是基于xml还是基于注解,并说明配置文件的位置
        注解:@ContextConfiguration
        属性:
            locations:指定xml文件位置。关键字classpath表示在类路径下
            classes:指定注解类所在的位置
        @RunWith(SpringJunit4ClassRunner.class)
        @ContextConfiguration(classes=SpringConfiguration.class)
        public class AccountServiceTest{
            //现在测试不关心IAccountService是如何获取到的,使用注解自动注入
            @Autowired
            private IAccountService as = null;
            //单元测试代码
            //单元测试代码可以直接使用as,即测试只关系成员方法是否正确
        }
    d. 当使用spring 5.0+版本时,要求Junit的版本为4.12+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值