spring 讲解

116 阅读8分钟

数据结构与算法之美 下栽: www.sanzhishu.top/655.html


Spring

Spring简介

Spring 是一个开源的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应

特点:

  • Spring 是一个开源免费的框架,容器;
  • Spring 是一个轻量级的框架,非入侵式的;
  • 控制反转 IoC,面向切面编程 AOP;
  • 对事务的支持,对框架的支持。

优点:

  • 方便解耦,简化开发
  • AOP编程的支持
  • 声明式事务的支持
  • 方便程序的测试
  • 方便集成各种优秀的框架
  • 降低JavaEE API的使用难度

Spring的体系结构:

Spring入门

Spring的开发步骤示意图:

Spring程序开发步骤

  1. 在maven导入Spring开发的基本包坐标

        org.springframework
        spring-context
        5.3.6

  1. 编写Dao接口和实现类
  2. 创建Spring核心配置文件
  3. 在Spring配置文件中配置UserDaoImpl
  4. 使用Spring的API获得Bean实例
public class UserDaoDemo {
    public static void main(String[] args) {
//        参数为spring配置文件
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //参数为配置文件中为该实现类配置的id
        UserDao userDao =(UserDao) app.getBean("userDao");
        userDao.save();
    }
}

​ 成功运行

之前运行提示:Error:java: 错误: 不支持发行版本 5,在pom.xml中添加该配置,11为我的java版本


    11
    11

Spring配置文件

Bean标签

  • 用于配置对象交由spring创建,默认情况下调用类的无参构造函数,不是无参构造函数不能创建成功
  • 基本属性:id:唯一标识 ​ class:全限定名称
  • 范围配置:scope:每次通过spring得到的bean实例对象是不同的实例对象或者是同一个(单例) 与此同时单例在就加载配置文件时就进入了无参构造,只要容器在对象一直存在;而多例在获得bean实例对象是进入无参构造,只要对象在使用一直存在,长时间不用被回收
  • Bean生命周期配置:
    • init-method:指定类中的初始化方法名称
指定该类中的save方法在初始化时调用,销毁同理:

  • destroy-method:指定类中销毁方法名称
  • Bean实例化三种方式:
    • 无参构造方法实例化:默认,见上
    • 工厂静态方法实例化:
StaticFactory是工厂,getUserDao是StaticFactory的方法

package com.myspring.dao.impl;

public class StaticFactory {
    public  static  UserDaoImpl getUserDao(){
        return  new UserDaoImpl();
    }
}
  • 工厂实例方法实例化

因为非static需要实例对象,所以创建

再讲两种联系起来

package com.myspring.dao.impl;

public class Factory {
    public   UserDaoImpl getUserDao(){
        return  new UserDaoImpl();
    }
}

依赖注入

  • 依赖注入是spring框架核心ioc的具体实现
  • 在编写程序时,层与层(例如业务层调用持久层方法)之间的依赖关系可以通过调用sprin来维护,简单来说就是让框架把持久层对象传入业务层,不用我们直接获取

两种方式:

  1. set方法:我的理解是相当于通过spring调用它的set方法
//业务层中
public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public  void save(){
        userDao.save();
    }
}
//外部层:
public class UserDaoDemo {
    public static void main(String[] args) {
//        参数为spring配置文件
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //参数为配置文件中为该实现类配置的id
        UserService userService =(UserService) app.getBean("userService");
        userService.save();
    }
}
//dao层代码和上面的一样
spring配置文件中

​ 简便方法:p命名空间方式(本质上还是set):

​ 使用方法:修改xml其他不变:


     xmlns:p="http://www.springframework.org/schema/p">

  1. 构造方法

​ 同理把业务层的set方法创建改成有参方法创建

在spring配置文件中:

其他数据注入

当然,除了可以注入bean实例,还可以注入其他数据:

  • 普通数据类型
  • 引用数据类型
  • 集合数据类型
本质还是set方法

                xiaoming
                xiahu

                aaa
                bbb

引入其他配置文件

当spring配置文件过大时,可以根据不同功能拆分成几个配置文件

那么只需要在主文件中引入拆分的配置文件:

Spring相关API

ApplicationContext:接口类型,代表引用上下文,可以通过其实例获得Spring容器中的Bean对象

其体系结构:

ApplicationContext的实现类

getBean()方法的使用

ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//通过bean实例的id得到
UserService userService =(UserService)
    app.getBean("userService");
//通过class类型寻找得到
app.getBean(UserService.class);

Spring配置数据源

数据源(连接池)

数据源的作用

常见数据源:DBCP、C3P0、BoneCP、Druid等

创建数据源

数据源的开发步骤:

  1. 导入数据源坐标和数据库驱动坐标(数据源可以自己选择导入那个公司的)

            mysql
            mysql-connector-java
            5.1.32
        '

            c3p0
            c3p0
            0.9.1.2

            com.alibaba
            druid
            1.1.10

            junit
            junit
            4.12
            test

  1. 创建数据源对象(c3p0),其他数据源的创建可以自行搜索
  2. 设置数据源的基本连接数据
  3. 使用数据源获取连接资源和归还资源
public class DataSourceTest {
//    这就是junit的
    @Test
    //测试手动创建c3p0数据源
    public  void test1() throws PropertyVetoException, SQLException {
//        创建数据源:这是c3p0的创建方法
        ComboPooledDataSource dataSource=new ComboPooledDataSource();
//        配置基本参数:一数据库驱动
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
//        数据库url
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/school");
//        用户名
        dataSource.setUser("root");
//        密码
        dataSource.setPassword("123456");
//        获取资源
        Connection connection = dataSource.getConnection();
//        测试connection是否为空
        System.out.println(connection);
        connection.close();
    }
}

运行测试结果:不为空所以成功 当然,为了降低耦合最好还是把数据库相关信息抽取出来为一个单独的配置文件 改进之后:

public class DataSourceTest {
//    这就是junit的
    @Test
    //测试手动创建c3p0数据源
    public  void test1() throws PropertyVetoException, SQLException {
        ResourceBundle rb = ResourceBundle.getBundle("jdbc");
        String driver = rb.getString("jdbc.driver");
        String url = rb.getString("jdbc.url");
        String username = rb.getString("jdbc.username");
        String password = rb.getString("jdbc.password");
        //创建数据源对象、设置连接参数
        //        创建数据源:这是c3p0的创建方法
        ComboPooledDataSource dataSource=new ComboPooledDataSource();
//        配置基本参数:一数据库驱动
        dataSource.setDriverClass(driver);
//        数据库url
        dataSource.setJdbcUrl(url);
//        用户名
        dataSource.setUser(username);
//        密码
        dataSource.setPassword(password);
//        获取资源
        Connection connection = dataSource.getConnection();
//        测试connection是否为空
        System.out.println(connection);
        connection.close();
    }
}

Spring 配置数据源

刚才是通过new来创建数据源,现在我们将数据源的创建权交给Spring容器去完成

配置文件中:

外部类中:

@Test
//测试手动创建c3p0数据源
public  void test1() throws PropertyVetoException, SQLException {
    ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    DataSource dataSource = app.getBean(DataSource.class);
    Connection connection = dataSource.getConnection();
    System.out.println(connection);
    connection.close();

}

如果要在spring配置文件中引入properties文件

Spring的注解开发

Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所有注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率

Spring原始注解

  • 主要替代配置
  • 原始注解有:注解 说明 @Component 使用在类上用于实例化Bean @Controller 使用在web层类上用于实例化Bean @Service 使用在service层类上用于实例化Bean @Repository 使用在dao层类上用于实例化Bean @Autowired 使用在字段上用于根据类型依赖注入 @Qualifier 结合@Autowired一起使用用于根据名称进行依赖注入 @Resource 相当于@Autowired+@Qualifier,按照名称进行注入 @Value 注入普通属性 @Scope 标注Bean的作用范围 @PostConstruct 使用在方法上标注该方法是Bean的初始化方法 @PreDestroy 使用在方法上标注该方法是Bean的销毁方法 下面例子配置和注解等同:
//
@Component("userDao")
public class UserDaoImpl implements UserDao{}
//  注入bean实例
//另外xml文件配置的方式该属性必须有set或者构造函数,但是注解方法可以省略
    @Autowired//按照数据类型从spring容器中进行匹配
    @Qualifier("userDao")//按照id的值从容器中进行匹配的,但是此处结合 @Autowired和 @Qualifier一起使用
    private  UserDao userDao;

最后,我们需要再配置文件中配置组件扫描:以识别注解

其他原始注解讲解:

  • @Controller、@Service、@Repository这三者和@Component作用完全相同但是,分别表示web层,service层、dao层的bean实例
  • @Resource(name="userDao")就等于@Autowired+@Qualifier("userDao")
  • @value:
//
@Value("12")
private  int age;
//这个东西需要在配置文件中已载入properties文件,具体见上
  @Value("${jdbc.driver}")
 private  String name;
  • @Scope("singleton"),参考bean的scope属性
  • @PostConstruct完全类似bean的init-method
  • @PreDestroy类似bean的destroy-method

新注解

除了原始注解外,我没还需要其他注解来覆盖其他原始注解无法实现的功能,例如:

  • 非自定义的bean
  • 加载properties文件配置
  • 组件扫描
  • 引入其他文件

新注解包括:

注解 说明 @Configuration 用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解 @ComponentScan 用于指定 Spring 在初始化容器时要扫描的包。作用和在Spring的xml配置文件中的<context:component-scan base-package="com"/>一样 @Bean 使用在方法上,标注将该方法的返回值存储到 Spring 容器中 @PropertySource 用于加载.properties 文件中的配置 @Import 用于导入其他配置类

新注解详解实例:

datasourceconfiguration配置类:

//加载properties配置文件
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {
    //    通过这种方法赋值
    @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("dataSource")//spring会将当前方法的返回值以指定名称存储到spring容器中,参数为id
    public DataSource getDataSource() throws PropertyVetoException {
        //        创建数据源:这是c3p0的创建方法
        ComboPooledDataSource dataSource=new ComboPooledDataSource();
//        配置基本参数:一数据库驱动
        dataSource.setDriverClass(driver);
//        数据库url
        dataSource.setJdbcUrl(url);
//        用户名
        dataSource.setUser(username);
//        密码
        dataSource.setPassword(password);
        return  dataSource;
    }
}
/*相当于xml配置文件中的:

核心配置类:

//标志该类是Spring的核心配置
@Configuration
//扫描com下的所有,相当于
@ComponentScan("com.myspring")
//导入datasourceconfiguration配置类,该类专注于数据库相关
@Import({DataSourceConfiguration.class})
public class SpringConfiguration {

}

外部类测试方法中:

//        配置文件为类时加载,区别于xml
        ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        DataSource dataSource = app.getBean(DataSource.class);
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();

运行成功。

Spring集成Junit

spring测试还是比较麻烦,可以通过Junit来简化

  • 让SpringJunit来复制spring容器的创建,但需要将配置文件的名称告诉他:可以简化这两句
    ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
    DataSource dataSource = app.getBean(DataSource.class);
  • 将需要bean自己在测试类中注入

集成Junit的步骤:

  1. 导入spring集成Junit的坐标 junit的坐标

    junit
    junit
    4.12
    test

spring集成junit坐标:


    org.springframework
    spring-test
    5.3.6

  1. 使用@Runwith注解替换原来的运行期
  2. 使用@ContextConfiguration指定配置文件或配置类
  3. 使用@Autowired注入需要测试的对象
  4. 创建测试方法进行测试
//java测试类中:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")//配置类参数写(classes={xxx.class})
public class SpringJunitTest {
   @Autowired
    private  UserService userService;

   @Test
   public  void test(){
       userService.save();
   }
}

关注夏壹分享发送:资源 获取深入讲解JVM虚拟机课程