Spring笔记

Spring简介

Spring框架由Rod Johnson开发,2004年发布了Spring框架的第一版。Spring是一个从实际开发中抽取出来的框架,因此它完成了大量开发中的通用步骤,留给开发者的仅仅是与特定应用相关的部分,从而大大提高了企业应用的开发效率。

Spring总结起来优点如下:

  • 低侵入式设计,代码的污染极低。
  • 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺。
  • Spring的IoC容器降低了业务对象替换的复杂性,提高了组件之间的解耦。
  • Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用。
  • Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问。
  • Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部。
    Spring框架的组成结构图如下所示:
    在这里插入图片描述

Spring的核心机制

管理Bean

程序主要是通过Spring容器来访问容器中的Bean,ApplicationContext是Spring容器最常用的接口,该接口有如下两个实现类:

  • ClassPathXmlApplicationContext: 从类加载路径下搜索配置文件,并根据配置文件来创建Spring容器。
  • FileSystemXmlApplicationContext: 从文件系统的相对路径或绝对路径下去搜索配置文件,并根据配置文件来创建Spring容器。
public class BeanTest{
    public static void main(String args[]) throws Exception{
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
        Person p = ctx.getBean("person", Person.class);
        p.say();
    }
}

Spring配置文件

在这里插入图片描述
在这里插入图片描述

Bean标签

1.属性

  • id:给对象在容器中提供一个唯一标识。用于获取对象。

  • class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。

  • scope:指定对象的作用范围。

    • singleton:默认值,单例的

    • prototype:多例的

    • request:WEB项目中,Spring创建一个Bean的对象,将对象存入到request域中

    • session:WEB项目中,Spring创建一个Bean的对象,将对象存入到session域中

    • globalSession:WEB项目中,应用在Portlet环境.如果没有Portlet环境那么globalSession相当于session

  • init-method:指定类中的初始化方法名称

  • destroy-method:指定类中销毁方法名称

在这里插入图片描述

2.bean的作用范围和生命周期

单例对象:scope="singleton":一个应用只有一个对象的实例。它的作用范围就是整个引用。
生命周期

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

多例对象:scope="prototype":每次访问对象时,都会重新创建对象实例。
生命周期

  • 对象出生:当使用对象时,创建新的对象实例。
  • 对象活着:只要对象在使用中,就一直活着。
  • 对象死亡:当对象长时间不用时,被java的垃圾回收器回收了。

3.实例化bean的三种方式

3.1、方式一

<!--在默认情况下:它会根据默认无参构造函数来创建类对象。如果bean中没有默认无参构造函数,将会创建失败-->
<bean id="customerService" class="com.itheima.service.impl.CustomerServiceImpl"/>

3.2、方式二

/**
 * 模拟一个静态工厂,创建业务层实现类
 */
public class StaticFactory {	
	public static ICustomerService createCustomerService(){
		return new CustomerServiceImpl();
	}
}
<!-- 此种方式是:
	 使用StaticFactory类中的静态方法createCustomerService创建对象,并存入spring容器
	 id属性:指定bean的id,用于从容器中获取
	 class属性:指定静态工厂的全限定类名
	 factory-method属性:指定生产对象的静态方法
 -->
<bean id="customerService" 
	  class="com.itheima.factory.StaticFactory" 
	  factory-method="createCustomerService"></bean>

3.3、方式三

/**
 * 模拟一个实例工厂,创建业务层实现类
 * 此工厂创建对象,必须现有工厂实例对象,再调用方法
 */
public class InstanceFactory {	
	public ICustomerService createCustomerService(){
		return new CustomerServiceImpl();
	}
}
<!-- 此种方式是:
		 先把工厂的创建交给spring来管理。
		然后在使用工厂的bean来调用里面的方法
		factory-bean属性:用于指定实例工厂bean的id。
		factory-method属性:用于指定实例工厂中创建对象的方法。
	-->
	<bean id="instancFactory" class="com.itheima.factory.InstanceFactory"></bean>
	<bean id="customerService" 
		  factory-bean="instancFactory" 
		  factory-method="createCustomerService"></bean>

3.4依赖注入

所谓的依赖注入,其实是当一个bean实例引用到了另外一个bean实例时spring容器帮助我们创建依赖bean实例并注入(传递)到另一个bean中。下面分别介绍setter注入和构造函数注入。

setter注入/设值注入

设值注入是指IoC容器使用属性的setter方法来注入被依赖的实例。这种注入方式比较简单、直观。
这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringDao的set方法(这是ioc的注入入口):

package com.bless.springdemo.action;  
public class SpringAction {  
	//注入对象springDao  
	private SpringDao springDao;  
	//一定要写被注入对象的set方法  
	public void setSpringDao(SpringDao springDao) {  
		this.springDao = springDao;  
    }  
	public void ok(){  
		springDao.ok();  
	}  
}

随后编写spring的xml文件,因为在SpringAction中有一个属性Springdao,所以要在标签中创建一个标签指定SpringDao。

标签中的name就是SpringAction类中的SpringDao属性名,ref指下面,

这样其实是spring将SpringDaoImpl对象实例化并且调用SpringAction的setSpringDao方法将SpringDao注入:

<bean name="springAction" class="com.bless.springdemo.action.SpringAction">  
   <property name="springDao" ref="springDao">property>  
</bean>  
<bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean> 

构造器注入

这种方式的注入是指带有参数的构造函数注入,看下面的例子,我创建了两个成员变量SpringDao和User,但是并未设置对象的set方法,所以就不能支持第一种注入方式,
这里的注入方式是在SpringAction的构造函数中注入,也就是说在创建SpringAction对象时要将SpringDao和User两个参数值传进来:

public class SpringAction {  
	//注入对象springDao  
	private SpringDao springDao;  
	private User user;  
	public SpringAction(SpringDao springDao,User user){  
		this.springDao = springDao;  
		this.user = user;  
		System.out.println("构造方法调用springDao和user");  
	}  
	public void save(){  
		user.setName("卡卡");  
		springDao.save(user);  
	}  
}  

在XML文件中同样不用的形式,而是使用标签,ref属性同样指向其它标签的name属性:

<bean name="springAction" class="com.bless.springdemo.action.SpringAction">    
	<constructor-arg ref="springDao">constructor-arg>  
	<constructor-arg ref="user">constructor-arg>  
</bean>  
<bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean>  
<bean name="user" class="com.bless.springdemo.vo.User"></bean> 

spring配置数据源

1.数据源开发步骤

  1. 导入数据源坐标和数据库驱动坐标
  2. 创建数据源对象
  3. 设置数据源基本连接数据
  4. 使用数据源获取连接资源和归还资源

2.手动创建数据源

  1. 在maven中添加相关依赖
<dependency>
	<groupId>c3p0</groupId>
	<artifactId>c3p0</artifactId>
	<version>0.9.1.2</version>
</dependency>

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

  1. 配置文件
<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>
  1. 创建C3P0连接池
@Test
public void test01() throws Exception {
	ComboPooledDataSource dataSource = new ComboPooledDataSource();
	dataSource.setDriverClass("com.mysql.jdbc.Driver");
	dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mybatis");
	dataSource.setUser("root");
	dataSource.setPassword("root");
	Connection conn = dataSource.getConnection();
	System.out.println(conn);
	dataSource.close();
}

3.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/mybatis"/>
    <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);

抽取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>

Spring容器加载properties文件

<context:property-placeholder location="xx.properties"/>
<property name="" value="${key}"/>


Spring注解开发

1. 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的销毁方法

注意:

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

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

使用@Compont或@Repository标识UserDaoImpl需要Spring进行实例化。

//@Component("userDao")
@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
    	System.out.println("save running... ...");
    }
}

使用@Compont@Service标识UserServiceImpl需要Spring进行实例化

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

//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
    /*@Autowired
    @Qualifier("userDao")*/
    @Resource(name="userDao")
    private UserDao userDao;
    @Override
    public void save() {       
   	  userDao.save();
    }
}

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

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Value("注入普通数据")
    private String str;
    @Value("${jdbc.driver}")
    private String driver;
    @Override
    public void save() {
        System.out.println(str);
        System.out.println(driver);
        System.out.println("save running... ...");
    }
}

使用@Scope标注Bean的范围

//@Scope("prototype")
@Scope("singleton")
public class UserDaoImpl implements UserDao {
   //此处省略代码
}

使用@PostConstruct标注初始化方法,使用@PreDestroy标注销毁方法

@PostConstruct
public void init(){
	System.out.println("初始化方法....");
}
@PreDestroy
public void destroy(){
	System.out.println("销毁方法.....");
}

2.Spring新注解

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

非自定义的Bean的配置:

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

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

引入其他文件:

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

@Configuration

@ComponentScan

@Import

@Configuration
@ComponentScan("com.itheima")
@Import({DataSourceConfiguration.class})
public class SpringConfiguration {
}

@PropertySource

@value

@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

@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;
} 

测试加载核心配置类创建Spring容器

@Test
public void testAnnoConfiguration() throws Exception {
ApplicationContext applicationContext = new 
    AnnotationConfigApplicationContext(SpringConfiguration.class);    
    UserService userService = (UserService)    
    applicationContext.getBean("userService");
    userService.save();
    DataSource dataSource = (DataSource) 
    applicationContext.getBean("dataSource");
    Connection connection = dataSource.getConnection(); 
    System.out.println(connection);
}

Spring整合Junit

1.原始Junit测试Spring的问题

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

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

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

2. 上述问题解决思路

让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它

将需要进行测试Bean直接在测试类中进行注入

3. Spring集成Junit步骤

①导入spring集成Junit的坐标

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

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

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

⑤创建测试方法进行测试

4. Spring集成Junit代码实现

①导入spring集成Junit的坐标

<!--此处需要注意的是,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();
    }
}

Spring集成Junit步骤

①导入spring集成Junit的坐标

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

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

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

⑤创建测试方法进行测试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
## Spring入门学习 首先认识下Spring的结构 ![架构图](http://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/image001.gif) 然后我们皆可以写我们的demo了 ### 我们的Bean类 对于bean的理解,希望大家是把他看成Object对象,他可以是任何对象,甚至是接口,甚至是抽象方法,当然,具体用法大家在以后的使用中会有所认识的; 写一个简单的bean类 ```java package mybatis.study.start.bean; import lombok.Setter; /** * @program: test * @description: helloworld * @author: cutedog * @create: 2019-02-18 22:48 **/ @Setter public class HelloWorld { private String name; public void pritlnHello(){ System.out.println("Spring 3:Hello"); } } ``` #### 写我们的配置文件 一般都是application.xml文件,放在idea的resource目录下,是一个bean注册的配置文件 内容如下: ```xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <bean id="helloBean" class="mybatis.study.start.bean.HelloWorld"> <property name="name" value="Yiibai" /> </bean> </beans> ``` list<provin> Map<city,provincecitymysqq
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值