Spring和SpringMvc(二)

一:IOC/DI配置管理第三方bean

       
本节将会去配置数据库连接池Druid和c3p0。
这里会用到spring—context
先导入依赖: mvn 的仓库 https://mvnrepository.com/ 中进行搜索
<dependency>
        <groupId> org.springframework </groupId>
        <artifactId> spring-context </artifactId>
        <version> 5.2.10.RELEASE </version>
</dependency>
(一)配置druid:
添加依赖
<dependency>
        <groupId> com.alibaba </groupId>
        <artifactId> druid </artifactId>
        <version> 1.1.16 </version>
</dependency>

配置文件:

<bean class = "com.alibaba.druid.pool.DruidDataSource" >
        <property name = "driverClassName" value = "com.mysql.jdbc.Driver" />
        <property name = "url" value = "jdbc:mysql://localhost:3306/spring_db" />
        <property name = "username" value = "root" />
        <property name = "password" value = "root" />
</bean>
driverClassName: 数据库驱动
url: 数据库连接地址
username: 数据库连接用户名
password: 数据库连接密码
数据库连接的四要素要和自己使用的数据库信息一致。

public static void main ( String [] args ) {
                ApplicationContext ctx = new
                ClassPathXmlApplicationContext ( "applicationContext.xml" );
                DataSource dataSource = ( DataSource ) ctx . getBean ( "dataSource" );
                System . out . println ( dataSource );
}

这里就可以实现了Druid的管理

(二)实现c3p0的管理:

<dependency>
        <groupId> mysql </groupId>
        <artifactId> mysql-connector-java </artifactId>
        <version> 5.1.47 </version>
</dependency>
<dependency>
        <groupId> c3p0 </groupId>
        <artifactId> c3p0 </artifactId>
        <version> 0.9.1.2 </version>
</dependency>

配置第三方bean

<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/spring_db" />
                <property name = "user" value = "root" />
                <property name = "password" value = "root" />
                <property name = "maxPoolSize" value = "1000" />
</bean>

这样就可以直接获得相应的连接了。

但是会发现这样会很不安全,很不安全。因为直接在注解配置文件中就展现出了账户密码。

(三)Properties的配置文件

依然是在resource下面去创建jdbc.properties文件,并添加数据。

jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc : mysql : //127.0.0.1 : 3306/spring_db
jdbc.username = root
jdbc.password = root

然后就是很重要的 开启context 命名空间

<?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" >
</beans>

之后在配置文件中context下就可以获取了jdbc的相应数据了

<context:property-placeholder location = "jdbc.properties" />
<bean id = "dataSource" class = "com.alibaba.druid.pool.DruidDataSource" >
<property name = "driverClassName" value = "${jdbc.driver}" />
<property name = "url" value = "${jdbc.url}" />
<property name = "username" value = "${jdbc.username}" />
<property name = "password" value = "${jdbc.password}" />
</bean>

当然了,至此就可以实现了读取properties的内容了。同时也可以了直接获取了name中这些的数值了。

现在又有了一个问题,就是说如果有多个properties需要加载呢

<context:property-placeholder
location = "jdbc.properties,jdbc2.properties" system-properties
mode = "NEVER" />
<!-- 方式二 -->
<context:property-placeholder location = "*.properties" system
properties-mode = "NEVER" />
<!-- 方式三 -->
<context:property-placeholder location = "classpath:*.properties"
system-properties-mode = "NEVER" />
<!-- 方式四 -->
<context:property-placeholder location = "classpath*:*.properties"
system-properties-mode = "NEVER" />

system-properties-mode="NEVER"其中的这句话就是说,不加载系统的属性,以防止某些时候,出现了加载了系统属性数值而没有加载你自己添加的数值。

方式一 : 可以实现,如果配置文件多的话,每个都需要配置
方式二 : *.properties 代表所有以 properties 结尾的文件都会被加载,可以解决方式一的问
题,但是不标准
方式三 : 标准的写法, classpath: 代表的是从根路径下开始查找,但是只能查询当前项目的根
路径
方式四 : 不仅可以加载当前项目还可以加载当前项目所依赖的所有项目的根路径下的
properties 配置文件

二:IOC/DI的注解开发

(一)容器的创建方式:

1类路径下的XML配置文件

ApplicationContext ctx = new
ClassPathXmlApplicationContext ( "applicationContext.xml" );

2文件系统下的XML配置文件

ApplicationContext ctx = new
FileSystemXmlApplicationContext ( "D:\\workspace\\spring\\spring_10_container\\s
rc\\main\\resources\\applicationContext.xml" );

耦合度较高不推荐使用。

3BeanFactory来创建IOC容器

Resource resources = new ClassPathResource ( "applicationContext.xml" );
BeanFactory bf = new XmlBeanFactory ( resources );
BookDao bookDao = bf . getBean ( BookDao . class );
bookDao . save ();
BeanFactory 是延迟加载,只有在获取 bean 对象的时候才会去创建
ApplicationContext 是立即加载,容器加载的时候就会创建 bean 对象
添加以下信息,也可以成为延迟加载
lazy-init = "true"

(二)bean的三种推荐方式:

1.BookDao bookDao = (BookDao) ctx.getBean("bookDao");

2BookDao bookDao = ctx.getBean("bookDao"BookDao.class);

3BookDao bookDao = ctx.getBean(BookDao.class);

(三)总结:

(四)注解配置:

删除配置文件中的bean对象

在源代码中加入@Component注解

@Component ( "bookDao" )
public class BookDaoImpl implements BookDao {
public void save () {
System . out . println ( "book dao save ..." );
}
}
@Component 注解不可以添加在接口上,因为接口是无法创建对象的。

为了让 Spring 框架能够扫描到写在类上的注解,需要在配置文件上进行包扫描
<context:component-scan base-package = "com.blue" />
component: 组件 ,Spring 将管理的 bean 视作自己的一个组件
scan: 扫描
base-package 指定 Spring 框架扫描的包路径,它会扫描指定包及其子包中的所有类上的注解。
包路径越多 [ :com.blue.dao.impl] ,扫描的范围越小速度越快
包路径越少 [ :com.blue], 扫描的范围越大速度越慢
一般扫描到项目的组织名称即 Maven groupId [ :com.blue] 即可。

BookServiceImpl 类上也添加 @Component 交给 Spring 框架管理

@Component还衍生出来了@Controller@Service@Repository这三个注解。

这三个注解的作用是一样的,为了更加好的区分表现层,业务层和数据层的类。

都放在类定义的上方,就是为了将该类设为spring管理的bean。

(五)纯注解开发模式:

虽然上面已经用到了注解开发的形式,但依然存在配置文件。

在下面的方法中可以使用类来替换。

(一)具体的实现纯注解

步骤一:

创建一个配置类来替代那个配置文件

public class SpringConfig{

}

步骤二:

添加一个注解@Configuration,将其标识为一个配置类。

步骤三:

在配置类上添加包扫描注解@ComponentScan替换<context:component-scan base-package=""/>

@Configuration

@ComponentScan("com.blue")

public class SpringConfig{

}

这样就替代了配置文件

@Configuration 注解用于设定当前类为配置类
@ComponentScan 注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式
@ComponentScan({com.blue.service","com.blue.dao"})
// 加载配置文件初始化容器
ApplicationContext ctx = new
ClassPathXmlApplicationContext ( "applicationContext.xml" );
// 加载配置类初始化容器
ApplicationContext ctx = new
AnnotationConfigApplicationContext ( SpringConfig . class );
(二)注解开发bean对象与生命周期

1.默认情况下产生的bean对象是单例的 如果在类上添加@scope则可以改变它的单例性质。

@Scope ( "prototype" )就会变成非单例的情况。
2 :@PostConstruct(初始化方法) @PreDestroy(销毁方法) 来进行生命周期的配置
< dependency >
                < groupId > javax . annotation </ groupId >
                < artifactId > javax . annotation - api </ artifactId >
                < version > 1.3 . 2 </ version >
</ dependency >

@Repository
 public class BookDaoImpl implements BookDao {
 public void save() {
         System.out.println("book dao save ...");
 }
 @PostConstruct //在构造方法之后执行,替换 init-method
 public void init() {
         System.out.println("init ...");
 }
 @PreDestroy //在销毁方法之前执行,替换 destroy-method
 public void destroy() {
         System.out.println("destroy ...");
 }
 }

(三)依赖注入:

1.选择按类型进行注入

在进行注入依赖的情况下,是使用的自动装配

@Service
public class BookServiceImpl implements BookService {
                @Autowired
private BookDao bookDao ;
                // public void setBookDao(BookDao bookDao) {
                // this.bookDao = bookDao;
        // }
public void save () {
                System . out . println ( "book service save ..." );
                bookDao . save ();
        }
}

注意 :
@Autowired 可以写在属性上,也可也写在 setter 方法上,最简单的处理方式是 写在属性上并将
setter 方法删除掉
为什么 setter 方法可以删除呢 ?
自动装配基于反射设计创建对象并通过暴力反射为私有属性进行设值
普通反射只能获取 public 修饰的内容
暴力反射除了获取 public 修饰的内容还可以获取 private 修改的内容
所以此处无需提供 setter 方法

@Autowired 是按照类型注入的,给 BookDao 的两个实现起了名称,它还是有两个 bean 对象,
为什么不报错 ?
@Autowired 默认按照类型自动装配,如果 IOC 容器中同类的 Bean 找到多个,就按照变量名和
Bean 的名称匹配。因为变量名叫 bookDao 而容器中也有一个 booDao ,所以可以成功注入。

2.按照名称进行注入:

当根据类型在容器中找到多个 bean, 注入参数的属性名又和容器中 bean 的名称不一致,这个时候该如何解决,就需要使用到@Qualifier 来指定注入哪个名称的 bean 对象。
@Service
public class BookServiceImpl implements BookService {
                @Autowired
                @Qualifier ( "bookDao1" )
private BookDao bookDao ;
public void save () {
                System . out . println ( "book service save ..." );
                bookDao . save ();
        }
}
@Qualifier 注解后的值就是需要注入的 bean 的名称。

注意:@Qualifier不能独立使用,必须和@Autowired一起使用

 简单类型的注入:

@Value ( "blue" )
private String name ;

注意数据格式需要匹配好。

这样直接赋值没有什么太大意思。

resources下准备properties文件 创建一个文件jdbc.properties

@Configuration
@ComponentScan ( "com.blue" )
@PropertySource ( "jdbc.properties" )// @PropertySource ({ "jdbc.properties" , "xxx.properties" })
public class SpringConfig {
}
@Repository ( "bookDao" )
public class BookDaoImpl implements BookDao {
@Value ( "${name}" )
private String name ;
public void save () {
System . out . println ( "book dao save ..." + name );
}
}

注意一下:propertyScource注解中不能够使用通配符,要不然就会报错。

3注解开发管理第三方bean

使用@Bean就可以实现直接bean的对象的创建

@Configuration
public class SpringConfig {
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
}

方案一实现起来有点小复杂, Spring 早就想到了这一点,于是又给我们提供了第二种方案。
这种方案可以不用加 @Configuration 注解,但是必须在 Spring 配置类上使用 @Import 注解手动引入
需要加载的配置类

public class JdbcConfig {
@Bean
public DataSource dataSource (){
DruidDataSource ds = new DruidDataSource ();
ds . setDriverClassName ( "com.mysql.jdbc.Driver" );
ds . setUrl ( "jdbc:mysql://localhost:3306/spring_db" );
ds . setUsername ( "root" );
ds . setPassword ( "root" );
return ds ;
}
}
@Import 参数需要的是一个数组,可以引入多个配置类。
@Configuration
//@ComponentScan("com.blue.config")
@Import ({ JdbcConfig . class })
public class SpringConfig {
}
现在的数据库连接四要素还是写在代码中,需要做的是将这些内容提
1.resources 目录下添加 jdbc.properties
2. 配置文件中提供四个键值对分别是数据库的四要素
3. 使用 @PropertySource 加载 jdbc.properties 配置文件
4. 修改 @Value 注解属性的值,将其修改为 ${key} key 就是键值对中的键的值

三Spring整合mybatis

导入依赖:

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.10.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
  </dependency>

  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
  </dependency>

  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
  </dependency>

  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.10.RELEASE</version>
  </dependency>

  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.0</version>
  </dependency>

</dependencies>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--读取外部properties配置文件-->
<properties resource="jdbc.properties"></properties>
<!--别名扫描的包路径-->
<typeAliases>
<package name="com.blue.entity"/>
</typeAliases>
<!--数据源-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}">
</property>
<property name="password" value="${jdbc.password}">
</property>
</dataSource>
</environment>
</environments>
<!--映射文件扫描包路径-->
<mappers>
<package name="com.blue.dao"></package>
</mappers>
</configuration>
第一行读取外部 properties 配置文件, Spring 有提供具体的解决方案 @PropertySource ,
要交给 Spring
第二行起别名包扫描,为 SqlSessionFactory 服务的,需要交给 Spring
第三行主要用于做连接池, Spring 之前我们已经整合了 Druid 连接池,这块也需要交给
Spring
前面三行一起都是为了创建 SqlSession 对象用的,那么用 Spring 管理 SqlSession 对象吗 ?
回忆下 SqlSession 是由 SqlSessionFactory 创建出来的,所以只需要将
SqlSessionFactory 交给 Spring 管理即可。
第四行是 Mapper 接口和映射文件 [ 如果使用注解就没有该映射文件 ] ,这个是在获取到
SqlSession 以后执行具体操作的时候用,所以它和 SqlSessionFactory 创建的时机都不在
同一个时间,可能需要单独管理。

接下来就是实现的具体方法:

1.创建好配置类:

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
public DataSource dataSource (){
DruidDataSource ds = new DruidDataSource ();
ds . setDriverClassName ( driver );
ds . setUrl ( url );
ds . setUsername ( userName );
ds . setPassword ( password );
return ds ;
}
}

创建mybatis配置类并且配置sqlsessionfactory

public class MybatisConfig {
// 定义 bean SqlSessionFactoryBean ,用于产生 SqlSessionFactory 对象
@Bean
public SqlSessionFactoryBean sqlSessionFactory ( DataSource dataSource ){
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean ();
// 设置模型类的别名扫描
ssfb . setTypeAliasesPackage ( "com.blue.eneity" );
// 设置数据源
ssfb . setDataSource ( dataSource );
return ssfb ;
}
// 定义 bean ,返回 MapperScannerConfigurer 对象
@Bean
public MapperScannerConfigurer mapperScannerConfigurer (){
MapperScannerConfigurer msc = new MapperScannerConfigurer ();
msc . setBasePackage ( "com.blue.dao" );
return msc ;
}
}

主配置类

@Configuration
@ComponentScan ( "com.blue" )
@PropertySource ( "classpath:jdbc.properties" )
@Import ({ JdbcConfig . class , MybatisConfig . class })
public class SpringConfig {
}

然后就可以去具体的运行了。

四:Spring整合Junit

其实核心,就是将spring中的那个容器弄进来就行,bean对象找到就行。

依赖

<dependency>
<groupId> junit </groupId>
<artifactId> junit </artifactId>
<version> 4.12 </version>
<scope> test </scope>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-test </artifactId>
<version> 5.2.10.RELEASE </version>
</dependency>
//设置类运行器
@RunWith(SpringJUnit4ClassRunner.class)
//设置Spring环境对应的配置类
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {
    //支持自动装配注入bean
    @Autowired
    private AccountService accountService;

    @Test
    public void testFindById(){
        System.out.println(accountService.findById(1));

    }

    @Test
    public void testFindAll(){
        System.out.println(accountService.findAll());
    }


}
单元测试,如果测试的是注解配置类,则使用 @ContextConfiguration(classes = 配置
.class)
单元测试,如果测试的是配置文件,则使用 @ContextConfiguration(locations={ 配置文件
,...})
Junit 运行后是基于 Spring 环境运行的,所以 Spring 提供了一个专用的类运行器,这个务必要设
置,这个类运行器就在 Spring 的测试专用包中提供的,导入的坐标就是这个东西
SpringJUnit4ClassRunner
上面两个配置都是固定格式,当需要测试哪个 bean 时,使用自动装配加载对应的对象,下面的工
作就和以前做 Junit 单元测试完全一样了

总结一下:

@Runwith就是放在测试类的上方,起到设置junit运行器的作用

@ContextConfiguration就是设置junit加载spring的核心配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值