zoukankan      html  css  js  c++  java
  • Spring系列之新注解配置+Spring集成junit+注解注入

    Spring系列之注解配置

    Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率
    你本来要写一段很长的代码来构造一个Beam对象,但是如果使用注解的话只要使用一个注解符号即可
    在这里插入图片描述

    下面我们来讲讲一些经常使用的注解符号
    @Component 使用类上用于实例化Bean
    @Controller 使用web层类上用于实例化Bean
    @Service 使用在Service层类上用于实例化service
    @Repository 使用在dao层类上用于实例化Bean
    @Autorwired 使用在字段上用于根据类型依赖注入
    @Qualifier 结合结合@Autowired一起使用根据名称进行依赖注入
    @Resource 相当于@Autowired+@Qualifier一起使用
    @Scope 标注bean的范围
    @PostConstruct 使用该在方法上标注该方法是Bean的初始化方法
    @PostDestory 使用在方法上标注该方法是Bean的销毁方法

    这三个没有什么区别,不过是为了在后期读代码的时候更加利于我们区分,比如看到@Controller就知道这是web层,看到@Service就知道这是service层

    @Component  使用类上用于实例化Bean
    @Controller    使用web层类上用于实例化Bean
    @Service        使用在Service层类上用于实例化service
    @Repository   使用在dao层类上用于实例化Bean
    

    所以我们只需讲一个即可,其他的使用方法均相同,这里我们使用@Component来讲解
    定义一个userDaolmp类

    package com.pjh.dao;
    import com.pjh.dao.Imp.userdao;
    import org.springframework.stereotype.Component;
    @Component("userDaoImp")
    public class userDaoImp implements userdao {
        public void save() {
            System.out.println("save");
        }
    }
    

    定义一个测试类测试

    @Test
        public void test(){
            ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
          userdao userDaoImp =(userdao) classPathXmlApplicationContext.getBean("userDaoImp");
          userDaoImp.save();
        }
    

    然后我们就发现了如下报错
    由蓝色的划线部分我们可以看出问题是:没有一个名叫userDaoImp的bean
    在这里插入图片描述
    这是为什呢?因为我们虽然写了注解,但是我们要让applicationContext.xml知道我们使用了注解,要告诉他哪里有个bean。所以我们在applicationContext中还需要加入以下配置

    命名空间:xmlns:context="http://www.springframework.org/schema/context
    约束路径http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    注解的组件扫描:
    <context:component-scan base-package="com.pjh"/>

    成功运行
    在这里插入图片描述

    接下来我们再来讲讲如何使用注解进行注入

    方式一:使用@Autowired+@Qualifier
    目的:创建一个userdao类将其注入带service类中

    userdao类代码

    package com.pjh.dao;
    import com.pjh.dao.Imp.userdao;
    import org.springframework.stereotype.Component;
    @Component("userDaoImp")
    public class userDaoImp implements userdao {
        public void save() {
            System.out.println("save");
        }
    }
    

    service类代码

    package com.pjh.service.Imp;
    import com.pjh.dao.Imp.userdao;
    import com.pjh.dao.userDaoImp;
    import com.pjh.service.service;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Repository;
    import javax.annotation.Resource;
    import javax.xml.bind.SchemaOutputResolver;
    
    @Repository("serviceImp")
    public class serviceImp implements service {
       @Autowired
       @Qualifier("userDaoImp")
       
       private userDaoImp userDaoImp;
        public void save() {
            System.out.println("sssssss");
           userDaoImp.save();
        }
    
    }
    

    测试类

    @Test
        public void test(){
            ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
          service service =(service) classPathXmlApplicationContext.getBean("serviceImp");
          service.save();
        }
    

    结果

    在这里插入图片描述

    方式二:使用@Resource()

    就是把 @Autowired + @Qualifier("userDaoImp")换成@Resource(name="userDaoImp"),其余代码均与方式一相同

    package com.pjh.service.Imp;
    import com.pjh.dao.Imp.userdao;
    import com.pjh.dao.userDaoImp;
    import com.pjh.service.service;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Repository;
    import javax.annotation.Resource;
    import javax.xml.bind.SchemaOutputResolver;
    @Repository("serviceImp")
    public class serviceImp implements service {
      /* @Autowired
       @Qualifier("userDaoImp")*/
        @Resource(name="userDaoImp")
       private userDaoImp userDaoImp;
        public void save() {
            System.out.println("sssssss");
           userDaoImp.save();
        }
    
    }
    

    结果

    在这里插入图片描述
    令人蛋碎的事情来了,报错了,意思是不支持版本5
    在这里插入图片描述
    解决方案:
    File->setting下设置项目的jdk版本
    在这里插入图片描述

    File->ProjectStruct下设置版本

    在这里插入图片描述
    结果

    在这里插入图片描述
    又报错了,这。。。。。我tm心态崩了呀

    在这里插入图片描述

    根据报错的内容是报了个空指针异常,这是为什么呢?为什么使用@Autowired + @Qualifier("userDaoImp")不报错换成@Resource(name="userDaoImp")就报空指针呢

    原因:jdk版本不支持

    解决方案:

    1.更换本地的jdk版本,最好jdk1.8以上,jdk9不支持有bug
    2.再maven.pom文件中引入如下依赖

    <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-annotations-api</artifactId>
            <version>7.0.47</version>
        </dependency>
    

    结果
    成功运行
    在这里插入图片描述终于解决完了
    在这里插入图片描述
    使用@Scope注解标注Bean的范围
    使用@Scope("prototype")

    package com.pjh.dao;
    import com.pjh.dao.Imp.userdao;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Component;
    @Component("userDaoImp")
    @Scope("prototype")
    public class userDaoImp implements userdao {
        public void save() {
            System.out.println("save");
        }
    }
    

    测试代码

    @Test
        public void test(){
            ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
            userdao userdao =(userdao) classPathXmlApplicationContext.getBean("userDaoImp");
            userdao userdao1 =(userdao) classPathXmlApplicationContext.getBean("userDaoImp");
            System.out.println(userdao);
            System.out.println(userdao1);
        }
    

    结果
    在这里插入图片描述

    使用@Scope("singleton")

    package com.pjh.dao;
    import com.pjh.dao.Imp.userdao;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Component;
    @Component("userDaoImp")
    @Scope("singleton")
    public class userDaoImp implements userdao {
        public void save() {
            System.out.println("save");
        }
    }
    

    结果

    在这里插入图片描述
    在这里顺便给大家复习复习singleton与prototype的区别吧
    singleton
    Bean的实例化个数:1个
    Bean的实例化时机:当Spring核心配置文件被加载时
    Bean的生命周期:
    对象创建:当应用加载时对象创建
    对象运行:只要容器在,对象就一直活着
    对象销毁:当应用卸载,容器销毁时
    prototype:在使用getBean方法的时候创建bean
    prototype
    Bean的实例化格式:多个
    Bean的实例化时机:当调用getBean()方法时,实例化Bean
    对象创建:当使用对象时,创建新的对象实例
    对象运行:只要对象在使用中,对象就一直存在
    对象销毁:对象长时间不使用,就会被java的垃圾回收机制回收

    初始化方法和销毁方法

    初始化方法
    @PostConstract

    @PostConstruct
        public void constract(){
            System.out.println("初始化方法");
        }
    

    销毁方法
    @PostDestroy

     @PreDestroy
        public void  destroy(){
            System.out.println("在对象销毁前执行");
        }
    

    @Value()进行注入

    package com.pjh.dao;
    import com.pjh.dao.Imp.userdao;
    import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Component;
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    @Component("userDaoImp")
    @Scope("singleton")
    public class userDaoImp implements userdao {
        public void save() {
            System.out.println("save");
            System.out.println("读取配置文件:"+one);
            System.out.println("普通类型:"+a);
        }
        @Value("${one.one}")
        private String one;
        @Value("4")
        private String a;
    
    }
    

    配置文件信息

    one.one=1
    

    applicationContext中添加的内容

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

    测试代码

    @Test
        public void test(){
            ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
            userdao userdao =(userdao) classPathXmlApplicationContext.getBean("userDaoImp");
            userdao.save();
        }
    

    结果

    在这里插入图片描述
    使用上面的注解还不可以全部替代xml配置文件,还需要使用注解替代的配置如下
    非自定义的Bean的配置:
    加载properties文件的配置:<context:property-placeholder>
    注解扫描的配置:context:component-scan
    引入其他文件:

    Spring新注解

    @Configuration 用于指定当前类是一个Spring配置类,创建容器时会从该类上加载注解,该类不能是匿名类与final类
    @ComponentScan 用于指定Spring在初始化容器的时候要扫描包
    作用与Spring中的此代码相同:context:component-scan
    @Bean 使用方法,将该方法的返回值返回到容器中
    @Import 用于导入其他配置类
    @PropertySource 用于加载properties文件中的配置

    案例

    核心配置类

    package com.pjh.config;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Import;
    import org.springframework.stereotype.Component;
    /*标志该类是核心配置类*/
    @Configuration
    /*扫描包*/
    @Component("com/pjh")
    /*导入其他配置类*/
    @Import(DataSourceConfig.class)
    public class Springconfig {
    }
    

    副配置类

    package com.pjh.config;
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.PropertySource;
    import javax.sql.DataSource;
    import java.beans.PropertyVetoException;
    /*加载配置文件*/
    @PropertySource("classpath:jdbc.properties")
    public class DataSourceConfig {
        @Value("${jdbc.driver}")
        private String driver;
        @Value("${jdbc.url}")
        private String url;
        @Value("${jdbc.username}")
        private String username;
        @Value("${jdbc.password}")
        private String password;
        /*Spring会将当前方法的返回值以指定名称存储到Spring容器中*/
        @Bean("dataSource")  
        public DataSource getDataSource() throws PropertyVetoException {
            ComboPooledDataSource dataSource = new ComboPooledDataSource();
            dataSource.setDriverClass(driver);
            dataSource.setJdbcUrl(url);
            dataSource.setUser(username);
            dataSource.setPassword(password);
            return dataSource;
        }
    }
    
    

    测试函数

    @Test
        public void test() throws SQLException {
            ApplicationContext applicationContext = new
                    AnnotationConfigApplicationContext(Springconfig.class);
          DataSource bean = (DataSource)applicationContext.getBean("dataSource");
            Connection connection = bean.getConnection();
            System.out.println(connection);
        }
    

    结果
    成功创建connection连接
    在这里插入图片描述

    Spring集成junit

    为什么使用Spring集成junit?
    在测试类中每个类都要写下面的两行代码

    ApplicationContext applicationContext = new
                    AnnotationConfigApplicationContext(Springconfig.class);
          DataSource bean = (DataSource)applicationContext.getBean("dataSource");
    

    这两行代码的作用是获取容器,不写的话报空指针异常
    为了让我们测试的时候不用进行反复的写上述两行的操作,我们使用Spring来集成junit,用springjunit来创建spring容器,
    我们只需将配置文件的名称告诉他们即可,将需要的bean直接在容器中进行注入

    Spring集成junit的步骤

    需要导入的jar包

    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
    

    这是我spring系列的学习文章,我也会不断的学习,文章如有错误还请批评指正,如有帮助大家可以点点关注,我们一同学习

    在这里插入图片描述

  • 相关阅读:
    套题 codeforces 361
    hdu 5720
    套题 codeforces 360
    套题 codeforces 359
    套题 bestcoder 84
    hdu 5748(求解最长上升子序列的两种O(nlogn)姿势)
    观django-messages包笔记
    django form
    省份、城市、区县三级联动Html代码
    django perm用法
  • 原文地址:https://www.cnblogs.com/pjhaymy/p/13714665.html
Copyright © 2011-2022 走看看