spring系列之——spring开发步骤

  • Post author:
  • Post category:其他

2、spring程序开发步骤

2.1、spring程序开发步骤

在这里插入图片描述

步骤:

①导入spring开发基本包的坐标 ==》导入maven依赖

②编写Dao接口和实现类 ==》创建Bean

③创建spring核心配置文件 ==》创建applicationContext.xml

④在spring配置文件中配置UserDaoImpl ==》在配置文件中进行配置

⑤使用spring的API获得Bean实例 ==》创建ApplicationContext对象getBean

2.2、Bean标签基本配置

用于配置对象交由spring来创建。默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功。

2.2.1、bean的基本属性:

  • id:Bean实例在容器中的唯一标识
  • class:Bean的全限定名称(反射默认无参构造创建)
  • scope:指对象的作用范围,取值如下:
取值范围 说明
singleton 默认值,单例的
prototype 多例的
request web项目中,spring创建一个bean对象,将对象存入到request域中
session web项目中,spring创建一个bean对象,将对象存入到session域中
global session web项目中,应用在portlet环境中,如果没有portlet环境那么globalsession相当于session

当scope的取值为 singleton 时:

bean的实例化个数:1个

bean的实例化时机:当spring核心文件被加载时,bean被实例化

bean的生命周期:

  • 对象创建:当应用加载,创建容器时,对象就被创建了
  • 对象运行:只要容器在,对象一直活着
  • 对象销毁:当应用卸载,销毁容器时,对象就被销毁了

当scope的取值为 prototype 时:

bean的实例化个数:多个

bean的实例化时机:当调用getBean()方法时,bean被实例化

bean的生命周期:

  • 对象创建:当使用对象时,创建新的对象实例
  • 对象运行:只要对象在使用中,对象一直活着
  • 对象销毁:当长时间不使用时,会被Java垃圾回收器回收

2.2.2、bean实例化的三种方式

  • 无参构造方法实例化
<bean id="user" class="com.spongebob.pojo.User"></bean>
  • 工厂静态方法实例化
public class StaticFactory {

    public static UserDao getUserDao(){
        return new UserDaoImpl();
    }
}
<bean id="user" class="com.spongebob.factory.StaticFactory" factory-method="getUserDao"></bean>
  • 工厂实例方法实例化
public class DynamicFactory {
    
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}
<bean id="factory" class="com.spongebob.factory.DynamicFactory" ></bean>
<bean id="userDao" factory-bean="factory" factory-method="getUserDao"/>

2.2.3、bean的依赖注入

Dependency Injecttion 是spring框架核心IOC的具体实现。

在编写程序时,通过控制反转,把对象的创建交给了spring,但是代码中不可能出现没有依赖的情况。IOC解耦只是降低他们的依赖关系,但是不会消除。例如:业务层仍会调用持久层的方法。

那种业务层和持久层的依赖关系,在使用spring之后,就让spring来维护了。简单说,就是坐等框架把持久层对象传入业务层,而不需要我们自己去获取。

注入方式:

  • 构造方法
public class UserService {

    private UserDao userDao;

    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }

    public UserService() {
    }

    public void save() {
        userDao.save();
    }
}
<bean id="userDao" class="com.spongebob.dao.impl.UserDaoImpl"></bean>

<bean id="userService" class="com.spongebob.service.UserService">
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
  • set方法
  1. 、简便方式

P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中:

首先引入P命名空间:

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

其次,需要修改注入方式:

<bean id="userService" class="com.spongebob.service.UserService" p:userDao-ref="userDao"/>

2)、常用set注入方式

<bean id="userDao" class="com.spongebob.dao.impl.UserDaoImpl"></bean>

        <bean id="userService" class="com.spongebob.service.UserService">
            <property name="userDao" ref="userDao"></property>
        </bean>
public class UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void save() {
        userDao.save();
    }
}

2.2.4、bean的依赖注入的数据类型

除了对象的引用可以注入,普通数据类型、集合等都可以在容器中进行注入。

注入数据的三种数据类型

  • 普通数据类型
  • 引用数据类型
public class UserDaoImpl implements UserDao {


    private String username;
    private  int age;

    public void setUsername(String username) {
        this.username = username;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public void save() {
        System.out.println(username+"===="+age);
        System.out.println("save running ..");
    }
}
<bean id="userDao" class="com.spongebob.dao.impl.UserDaoImpl">
            <property name="username" value="tuut"/>
            <property name="age" value="18"/>
</bean>
  • 集合数据类型
public class UserDaoImpl implements UserDao {

    private List<String> strList;
    private Map<String, User> userMap;
    private Properties properties;

    public void setStrList(List<String> strList) {
        this.strList = strList;
    }

    public void setUserMap(Map<String, User> userMap) {
        this.userMap = userMap;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public void save() {
        
        System.out.println("save running ..");
    }
}
<bean id="userDao" class="com.spongebob.dao.impl.UserDaoImpl">
    <property name="strList">
        <list>
            <value>aaa</value>
            <value>bbb</value>
            <value>ccc</value>
        </list>
    </property>
    <property name="userMap">
        <map>
            <entry key="u1" value-ref="user1"></entry>
            <entry key="u2" value-ref="user2"></entry>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key="p1">pp1</prop>
            <prop key="p2">pp2</prop>
        </props>
    </property>
</bean>

<bean id="user1" class="com.spongebob.pojo.User">
    <property name="name" value="tutu"/>
</bean>

<bean id="user2" class="com.spongebob.pojo.User">
    <property name="name" value="rebing"/>
</bean>

2.2.5、引入其他配置文件

实际开发中,spr的配置内容非常多,导致spring配置很繁杂且体积很大,所以可以将部分配置拆解到其他配置文件中,而spring主配置文件通过import标签进行加载:

<import resource="applicationContext-xxx.xml"/>

2.2.6、spring的重点配置

< bean >标签

​ id属性:在容器中Bean实例化的唯一标识,不允许重复

​ class属性:要实例化的Bean的全限定名

​ scope属性:Bean的作用范围,常用的是Singleton(默认)和prototype

​ < property >标签:属性注入

​ name属性:属性名称

​ value属性:属性值ref属性:注入的对象引用值

​ < list >标签

​ < map >标签

​ < properties >标签

​ < constructor-arg >标签:有参构造注入

< import >标签:导入其他的spring的分文件

2.3、Spring相关API

2.3.1、ApplicationContext的实现类

1)ClassPathXmlApplicationContext

它是从类的根路径下加载配置文件,推荐使用这种

2)FileSystemXmlApplicationContext

它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置

3)AnnotationConfigApplicationContext

当使用注解配置容器对象时,需要用此类来创建spring容器。它用来读取注解。

2.3.2、getBean()方法的使用

Object getBean(String var1) throws BeansException;

<T> T getBean(String var1, Class<T> var2) throws BeansException;

2.4、Spring配置数据源

数据源(连接池)的作用:

  • 数据源(连接池)是提高程序性能出现的
  • 事先实例化数据源,初始化部分连接资源
  • 使用链接资源时从数据源中获取
  • 使用完毕后将连接资源归还给数据源

常见的数据源(连接池):DBCP、C3P0、BoneCP、Druid等

2.4.1、数据源的开发步骤

①导入数据源的jar包和数据库驱动jar包

<dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
</dependency>

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.5</version>
</dependency>

②创建数据源对象

③设置基本的参数信息(4个基本信息)

④使用数据源获取连接资源和归还连接资源

 	@Test
    // 测试手动创建 c3p0 数据源
    public void test1() throws PropertyVetoException, SQLException {

        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/websites");
        dataSource.setUser("root");
        dataSource.setPassword("admin");

        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }

打印结果com.mchange.v2.c3p0.impl.NewProxyConnection@1e67b872

	@Test
    // 测试手动创建 druid 数据源
    public void test2() throws PropertyVetoException, SQLException {

        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/websites");
        dataSource.setUsername("root");
        dataSource.setPassword("admin");

        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }

打印结果com.mysql.cj.jdbc.ConnectionImpl@13c78c0b

通过编写jdbc.properties文件。

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/websites
jdbc.username=root
jdbc.password=admin

使用ResourceBundle读取配置jdbc.properties文件。

	@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");

        //创建数据源 设置连接参数
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);

        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();

    }

2.4.2、使用spring配置数据源

可以将DataSource的创建权交由Spring容器去完成

  • DataSource有无参构造方法,而Spring默认就是通过无参构造方法实例化对象的

  • DataSource要想使用需要通过set方法设置数据库连接信息,而Spring可以通过set方法进行字符串注入

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
    <property name="user" value="root"/>
    <property name="password" value="root"/>
</bean>

测试从容器中获取数据源:

ApplicationContext applicationContext = new 
ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) 
applicationContext.getBean("dataSource");
Connection connection = dataSource.getConnection();
System.out.println(connection);

2.4.3、抽取jdbc配置文件

applicationContext.xml加载jdbc.properties配置文件获得连接信息。

首先,需要引入context命名空间和约束路径:

  • 命名空间:xmlns:context=“http://www.springframework.org/schema/context”

  • 约束路径:http://www.springframework.org/schema/context

    ​ http://www.springframework.org/schema/context/spring-context.xsd

<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" 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>

2.5、spring注解开发

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

2.5.1、spring原始注解主要代替bean的配置

注解 说明
@Component 使用在类上,用于实例化bean
@Controller 使用在web层类上,用于实例化bean
@Service 使用在service层类上,用于实例化bean
@Respository 使用在dao层类上,用于实例化bean
@Autowired 使用在字段上,用于根据类型依赖注入
@Qualifier 结合@Autowired一起使用,用于根据名称进行依赖注入
@Resource 相当于@Autowired+@Qualifired,按照名称进行注入
@Value 注入普通属性
@Scope 标注bean的作用范围
@PostConstruct 使用在方法上,标注该方法是bean的初始化方法
@PreDestroy 使用在方法上,标注该方法是bean的销毁方法

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

<!--注解的组件扫描--> 
<context:component-scan base-package="com.spongebob"></context:component-scan>

使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下:

  • 非自定义的Bean的配置:< bean>
  • 加载properties文件的配置:< context:property-placeholder>
  • 组件扫描的配置:< context:component-scan>
  • 引入其他文件:< import>

2.5.2、spring新注解

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



@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(name="dataSource")
public DataSource getDataSource() throws PropertyVetoException {
    
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    dataSource.setDriverClass(driver);
    dataSource.setJdbcUrl(url);
    dataSource.setUser(username);
    dataSource.setPassword(password);
    return dataSource; 
}

2.6、spring集成Junit

2.6.1 原始Junit测试Spring的问题

在测试类中,每个测试方法都有以下两行代码:

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

这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。

解决思路:

  • 让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它。
  • 将需要进行测试Bean直接在测试类中进行注入。

2.6.2 spring集成Junit步骤

① 导入spring集成Junit的jar包

② 使用@Runwith注解替换原来的运行期

③ 使用@ContextConfiguration指定配置文件或配置类

④ 使用@Autowired注入需要测试的对象

⑤ 创建测试方法进行测试

<!--此处需要注意的是,spring5 及以上版本要求 junit 的版本必须是 4.12 及以上--> <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.12</version>
    <scope>test</scope>
</dependency>
//使用@Runwith注解替换原来的运行期
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringJunitTest {
    
}
//使用@ContextConfiguration指定配置文件或配置类
@RunWith(SpringJUnit4ClassRunner.class)
//加载spring核心配置文件
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//加载spring核心配置类
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
}
//使用@Autowired注入需要测试的对象
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
    @Autowired
    private UserService userService; 
}
//创建测试方法进行测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
    
    @Autowired
    private UserService userService;
    
    @Test
    public void testUserService(){
    	userService.save();
    } 
}

版权声明:本文为Good_omen原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。