Spring注解的基本使用------------注解简化原有的配置文件方式查询数据库中数据(@Respository @Service @Autowrited等)

Spring基本注解的使用

学习基于注解的IOC配置,大家脑海里首先得有一个认知,即注解配置和xml要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。

首先创建模板如图的测试格式:

Spring注解的基本使用------------注解简化原有的配置文件方式查询数据库中数据(@Respository @Service @Autowrited等)_第1张图片

用于创建对象的注解

@Component,@Repository,@Service,@Controller

注解 说明
@Component 使用在类上用于实例化Bean
@Controller 使用在Web层类上用于实例化Bean
@Service 使用在Service层类上用于实例化Bean
@Repository 使用在dao层类上用于实例化Bean

注意:

使用注解进行开发时,需要在application.xml中配置组件扫描,作用是指定哪个包及七子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法

示例代码:


<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-3.0.xsd">

<context:component-scan base-package="com.etime">context:component-scan>
beans>

使用@Component或者@Repository标识StudentDaoImpl需要对其进行Spring 实例化。

示例代码:

package com.etime.dao;

public interface StudentDao {
    void show();
}




package com.etime.dao.Impl;

import com.etime.dao.StudentDao;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

//@Component("sd")
@Repository("sd")//@Component和@Component都能够达到相同的效果,但是@Repository只能实例对象dao层
public class StudentDaoImpl implements StudentDao {
    @Override
    public void show() {
        System.out.println("这是studentDaoImpl的方法");
    }
}

使用@Component或者@Service标识StudentServiceImpl需要Spring进行实例化

示例代码:

package com.etime.service;

public interface StudentService {
    void show();
}



package com.etime.service.Impl;

import com.etime.service.StudentService;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

//@Component("ss") 之所以这里也可以用@Component的原因是因为该注解既可以用在dao层也可以用在service层
@Service("ss")
public class StudentServiceImpl implements StudentService {
    @Override
    public void show() {
        System.out.println("这是studentServiceImpl里的方法");
    }
}

用@Test进行测试上述代码

示例代码:

package com.etime.demo;

import com.etime.dao.StudentDao;
import com.etime.service.StudentService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StudentTest {
    @Test
    public void st01(){
        //加载application.xml解析文件
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        //实例对象StudentDao
        StudentDao studentDao =(StudentDao) context.getBean("sd");
        studentDao.show();//调用studentDao实现方法

        //实例对象StudentService
        StudentService service=(StudentService) context.getBean("ss");
        service.show();//调用studentService实现方法
        
    }
}

运行结果:

Spring注解的基本使用------------注解简化原有的配置文件方式查询数据库中数据(@Respository @Service @Autowrited等)_第2张图片

用于注入数据的注解

@Value,@Resource,@Autowrited,@Qualiffer

注解 说明
@Value 注入普通属性
@Autowired 自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他bean类型,当有多个类型匹配时,使用要注入的对象变量名称作为bean的id,在spring容器查找,找到了也可以注入成功。找不到就报错。如果IOC容器(即反转控制)当中有多个接口得实现类,首先根据类型自动装配,然后再根据名称自动装配。
@Qualifier 结合@Autowired一起使用用于根据名称进行依赖注入
@Resource 相当于@Autowired+Qualifier,按照名称进行注入,是java提供的,不是框架提供的

使用@Value进行字符串的注入

示例代码:

@Value("字符串String Hello World")
    private String string;
    public void addStudent(){
        System.out.println(string);
        System.out.println("这样开始增加学生信息了");
    }

使用@Autowired或者@Autowired+@Qulifier或者@Resource进行userDao的注入

方法一只使用@Autowired

package com.etime.service.Impl;

import com.etime.dao.StudentDao;
import com.etime.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

//@Component("ss") 之所以这里也可以用@Component的原因是因为该注解既可以用在dao层也可以用在service层
@Service("ss")
public class StudentServiceImpl implements StudentService {
    @Autowired//只使用@Autowired注解把dao层的类注入
    private StudentDao studentDao;
    
    @Override
    public void show() {
        studentDao.show();
        System.out.println("这是studentServiceImpl里的方法");
    }
}

第二种方法

package com.etime.service.Impl;

import com.etime.dao.StudentDao;
import com.etime.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

//@Component("ss") 之所以这里也可以用@Component的原因是因为该注解既可以用在dao层也可以用在service层
@Service("ss")
public class StudentServiceImpl implements StudentService {
    @Autowired//只使用@Autowired注解把dao层的类注入
    @Qualifier("sd")//即使用@Qualifier又使用@Autowired注解将dao层的类注入
    private StudentDao studentDao;
    
    @Override
    public void show() {
        studentDao.show();
        System.out.println("这是studentServiceImpl里的方法");
    }
}

第三种方法

package com.etime.service.Impl;

import com.etime.dao.StudentDao;
import com.etime.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

//@Component("ss") 之所以这里也可以用@Component的原因是因为该注解既可以用在dao层也可以用在service层
@Service("ss")
public class StudentServiceImpl implements StudentService {
//    @Autowired//只使用@Autowired注解把dao层的类注入
//    @Qualifier("sd")//即使用@Qualifier又使用@Autowired注解将dao层的类注入
    @Resource(name = "sd")//只使用当前@Resource一个注解能够解studentDao dao层的bean注入
    private StudentDao studentDao;

    @Override
    public void show() {
        studentDao.show();
        System.out.println("这是studentServiceImpl里的方法");
    }
}

测试:

示例代码:

@Test
    public void st02(){
        //加载application.xml解析文件
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");

        //dao层已经通过注解注入的方式代替了,不需要重新进行实例化
        //实例对象StudentDao
//        StudentDao studentDao =(StudentDao) context.getBean("sd");
//        studentDao.show();//调用studentDao实现方法

        //实例对象StudentService
        StudentService service=(StudentService) context.getBean("ss");
        service.show();//调用studentService实现方法

    }

运行结果:

Spring注解的基本使用------------注解简化原有的配置文件方式查询数据库中数据(@Respository @Service @Autowrited等)_第3张图片

和生命周期相关的注解

@PostConstruct @PreDestroy

注解 说明
@PostConstruct 使用在方法上标注该方法是Bean的初始化方法
@PreDestroy 使用在方法上标注该方法是Bean的销毁方法

使用@PostConstruct标注初始化方法,使用@PreDestory标注销毁方法。注意,这两个注解是java提供的,不是spring提供的

示例代码:

package com.etime.dao.Impl;

import com.etime.dao.StudentDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

//@Component("sd")
@Repository("sd")//@Component和@Component都能够达到相同的效果,但是@Repository只能实例对象dao层
public class StudentDaoImpl implements StudentDao {

//    @Value("字符串String Hello World")
//    private String string;
//    public void addStudent(){
//        System.out.println(string);
//        System.out.println("这样开始增加学生信息了");
//    }
    
    @PostConstruct
    public void init(){
        System.out.println("studentDao被初始化了");
    }

    @Override
    public void show() {
        System.out.println("这是studentDaoImpl的方法");
    }
    
    @PreDestroy
    public void destroy(){
        System.out.println("studentDao被摧毁了");
    }
    
}

测试:

    @Test
    public void st03(){
        //加载application.xml解析文件
        ClassPathXmlApplicationContext context= new ClassPathXmlApplicationContext("application.xml");
        StudentDao studentDao= (StudentDao) context.getBean("sd");//实例化studentDao类
        studentDao.show();//调用studentDao里面的方法发
        context.close();
    }

运行结果:

Spring注解的基本使用------------注解简化原有的配置文件方式查询数据库中数据(@Respository @Service @Autowrited等)_第4张图片

通过注解的方式从数据库获取学生信息

Spring基于注解的IOC

建立如图的maven模块

Spring注解的基本使用------------注解简化原有的配置文件方式查询数据库中数据(@Respository @Service @Autowrited等)_第5张图片

构建maven工程,添加框架技术依赖

注意:这里的依赖根据自己使用的数据库版本添加,我这里使用的是mysql8.0

示例代码:

pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-compiler-pluginartifactId>
                <configuration>
                    <source>6source>
                    <target>6target>
                configuration>
            plugin>
        plugins>
    build>

    <properties>
        <spring.version>5.2.5.RELEASEspring.version>
    properties>

    <groupId>com.etimegroupId>
    <artifactId>sdartifactId>
    <version>1.0-SNAPSHOTversion>

    <dependencies>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>${spring.version}version>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>${spring.version}version>
        dependency>
        
        
        
        
        
        

        
        
        
        
        
        

        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>8.0.11version>
        dependency>

        
        <dependency>
            <groupId>com.mchangegroupId>
            <artifactId>c3p0artifactId>
            <version>0.9.5version>
        dependency>

        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
            <scope>testscope>
        dependency>

        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-testartifactId>
            <version>${spring.version}version>
        dependency>
    dependencies>
project>

application.xml


<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-3.0.xsd">

<context:component-scan base-package="com.etime">context:component-scan>
    
    <context:property-placeholder location="classpath:jdbc.properties"/>
    
    <bean id="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    bean>
beans>

jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_school?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=h123456

使用注解配置管理的资源

示例代码:

dao:

package com.etime.dao;

import com.etime.entity.Student;

import java.util.List;

public interface StudentDao {
    List<Student> getStudent();
}

daoImpl:

package com.etime.dao.Impl;

import com.etime.dao.StudentDao;
import com.etime.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

//@Component("sd")
@Repository("sd")//@Component和@Component都能够达到相同的效果,但是@Repository只能实例对象dao层
public class StudentDaoImpl implements StudentDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public List<Student> getStudent() {
        List<Student> list=null;
        String sql="select * from student";
        list=jdbcTemplate.query(sql,new BeanPropertyRowMapper<Student>(Student.class));
        return list;
    }
}

service:

package com.etime.service;

import com.etime.entity.Student;

import java.util.List;

public interface StudentService {
    List<Student> getAllStudent();
}

serviceImpl:

package com.etime.service.Impl;

import com.etime.dao.StudentDao;
import com.etime.entity.Student;
import com.etime.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

//@Component("ss") 之所以这里也可以用@Component的原因是因为该注解既可以用在dao层也可以用在service层
@Service("ss")
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentDao studentDao;

    @Override
    public List<Student> getAllStudent() {
        return studentDao.getStudent();
    }
}

测试:

示例代码 :

        @Test
    public void st04(){
        //加载application.xml解析文件
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        StudentService service = (StudentService) context.getBean("ss");
        List<Student>  list= service.getAllStudent();
        System.out.println(list);
    }

运行结果:

Spring注解的基本使用------------注解简化原有的配置文件方式查询数据库中数据(@Respository @Service @Autowrited等)_第6张图片

Spring 纯注解配置

通过上述案例可知上述的注解还不能够全部替换xml配置之文件,好需要进行注解替代配置

非定义的Bean配置:@Bean

加载proerties文件的配置:context:property-placeholder

组件扫描的配置:context:component-scan

引入其他文件的注解:@import

上述注解的说明:

注解 说明
@Configuration 用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解,作用等价于application.xml配置文件
@ComponentScan 用于指定Spring 在初始化容器时扫描包。作用和在Spring的xml配置文件中的一样
@Bean 使用在方法上,标注将该方法的返回值存储到Spring容器中。id的值默认是方法的名称,可以自定义id的值
@PropertySource 用于加载xxxx.properties 文件中的配置 结合@Value()取配置文件的值
@Import 用于导入其他配置类

jdbc.properties

示例代码:

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_school?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=h123456

在util工具包内创建DataSourceConfig.java类

代码:

package com.etime.util;

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 org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

/**
 * 做数据库相关配置
 * 读取properties文件内容
 * 根据读取的内容生成连接池对象
 * 根据连接池对象获取JdbcTemplate对象
 * */
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfig {
    @Value("${jdbc.driver}")
    private String driverClass;

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

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

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

    public DataSource getDataSource(){
        ComboPooledDataSource ds= new ComboPooledDataSource();
        try {
            ds.setDriverClass(driverClass);
            ds.setJdbcUrl(jdbcUrl);
            ds.setUser(user);
            ds.setPassword(password);
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        return ds;
    }

    @Bean(name="jdbcTemplate")
    public JdbcTemplate getJdbcTemplate(){
        return new JdbcTemplate(getDataSource());
    }
}

同样创建SpringConfig.java类

代码:

package com.etime.util;

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

//指定当前类的配置类相当于application.xml
@Configuration
@Import(DataSourceConfig.class)//导入连接数据
@ComponentScan("com.etime")//扫描文件
public class SpringConfig {
}

上述就能够彻底替换了application.xml配置文件内的内容:

由第一种中方式下进行改造后将不再需要application.xml文件

修改后:

测试:

代码

@Test
    public void st05(){
        //加载配置类
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        StudentService service = (StudentService) context.getBean("ss");
        List<Student>  list= service.getAllStudent();
        System.out.println(list);
    }

运行结果:

Spring注解的基本使用------------注解简化原有的配置文件方式查询数据库中数据(@Respository @Service @Autowrited等)_第7张图片

Spring 整合JUnit

为了测试使用JUnit单元测试,但是在开发中将不适用该技术点时,不影响开发效果,但是可能影响开发效率。所以尽量避免代码重复性。

IOC测试类中的问题和解决

添加依赖(在pom.xml中)

		<dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-testartifactId>
            <version>${spring.version}version>
        dependency>

使用注解完成容器的加载

@RunWith:替换原有运行器

@ContextConfiguration:指定Spring配置文件的位置

@Autowired:给测试类中的变量注入数据

示例代码:StudentTest.java

package com.etime.demo;

import com.etime.dao.StudentDao;
import com.etime.entity.Student;
import com.etime.service.StudentService;
import com.etime.util.SpringConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
//加载Spring的配置类,生成容器对象
@ContextConfiguration(classes = {SpringConfig.class})
public class StudentTest {
    
    @Autowired
    private ApplicationContext context;

    @Test
    public void st05(){
        StudentService service = (StudentService) context.getBean("ss");
        List<Student>  list= service.getAllStudent();
        System.out.println(list);
    }
}

运行结果:

Spring注解的基本使用------------注解简化原有的配置文件方式查询数据库中数据(@Respository @Service @Autowrited等)_第8张图片

你可能感兴趣的:(Spring,Java,spring,java,intellij-idea,junit,后端)