spring使用入门

之前一直活在c/c++的世界里,最近来公司实习,项目上需要使用java spring的框架,本篇文章着重在于对spring框架进行最简单的配置和使用。

1.为何要引入spring

// 1. 实体类
class User{
}

//2. dao
class  UserDao{
   .. 访问db
}

//3. service
class  UserService{
    UserDao userDao = new UserDao();
}

//4. action
class  UserAction{
    UserService userService = new UserService();

    ..
    拿到数据或结果
}

用户访问:
/user.action ----> Tomcat (服务器创建Action、Service、dao

思考:

  1. 对象创建创建能否写死?
  2. 对象创建细节
    对象数量
    action 多个 【维护成员变量】
    service 一个 【不需要维护公共变量】
    dao 一个 【不需要维护公共变量】
    创建时间
    action 访问时候创建
    service 启动时候创建
    dao 启动时候创建
  3. 对象的依赖关系
    action 依赖 service
    service依赖 dao

=======================================================
总结:
spring就是解决上面的问题的!
简单来说,就是处理对象的创建的、以及对象的依赖关系!

2.专业术语了解

组件/框架设计

  • 侵入式设计:引入了框架,对现有的类的结构有影响;即需要实现或继承某些特定类。(例如:structs)
  • 非侵入式设计:引入了框架,对现有的类结构没有影响。(例如:Hibernate框架 / Spring框架)
  • 控制反转:Inversion on Control , 控制反转 IOC。对象的创建交给外部容器完成,这个就做控制反转。
class UserAction{
    //需要什么,就创建什么,“控制正转”
    IUserService userService = new UserService();
}

class UserAction{
    private IUserService userService;
    //对象的创建交给别人,叫控制反转  [依赖注入]
    public IUserService setUserService(IUserService userService){
        this.userService = userService;
   }
}
  • 依赖注入:处理对象的依赖关系
    区别:
    控制反转(IOC), 解决对象创建的问题 【对象创建交给别人】。
    依赖注入,在创建完对象后, 对象的关系的处理就是依赖注入 。【通过set方法依赖注入】
  • AOP:面向切面编程。切面,简单来说来可以理解为一个类,由很多重复代码形成的类。切面举例:事务、日志、权限;

3.Spring框架

3.1.概述

Spring框架,可以解决对象创建以及对象之间依赖关系的一种框架。且可以和其他框架一起使用;Spring与Struts, Spring与hibernate(起到整合(粘合)作用的一个框架)。
Spring提供了一站式解决方案:

  • Spring Core是spring的核心功能: IOC(控制反转)容器, 解决对象创建及依赖关系

  • Spring Web是Spring对web模块的支持。可以与struts整合,让struts的action创建交给spring。spring mvc模式。

  • Spring DAO Spring 对jdbc操作的支持 【JdbcTemplate模板工具类】

  • Spring ORM spring对orm的支持: 既可以与hibernate整合,【session】也可以使用spring的对hibernate操作的封装

  • Spring AOP 切面编程

  • SpringEE spring 对javaEE其他模块的支持

3.2.开发流程

3.2.1.源码, jar文件:spring-framework-3.2.5.RELEASE

在3.0以上的版本中,源码中只有spring的核心功能包。
在3.0以下的版本,源码有spring种相关的所有包。【spring功能包 + 依赖包】

commons-logging-1.1.3.jar           日志
spring-beans-3.2.5.RELEASE.jar        bean节点
spring-context-3.2.5.RELEASE.jar       spring上下文节点
spring-core-3.2.5.RELEASE.jar         spring核心功能
spring-expression-3.2.5.RELEASE.jar    spring表达式相关表

以上是必须引入的5个jar文件,在项目中可以用户库管理!
3.2.2.核心配置文件: applicationContext.xml

Spring配置文件:applicationContext.xml 或者叫做bean.xml
xml文件书写约束:

<beansxmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:p="http://www.springframework.org/schema/p" 
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>
3.2.3.得到对象
package cn.itcast.a_hello;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class App1_get_ioc {

 // 1. 通过工厂类得到IOC容器创建的对象
 @Test
 public void testIOC() throws Exception {
 // 创建对象
 // User user = new User();
 
 // 现在,把对象的创建交给spring的IOC容器
 Resource resource = new ClassPathResource("cn/itcast/a_hello/applicationContext.xml");
 // 创建容器对象(Bean的工厂), IOC容器 = 工厂类 + applicationContext.xml
 BeanFactory factory = new XmlBeanFactory(resource);
 // 得到容器创建的对象
 User user = (User) factory.getBean("user");
 
 System.out.println(user.getId());
 
 }
 
 //2. (方便)直接得到IOC容器对象 
 @Test
 public void testAc() throws Exception {
 // 得到IOC容器对象
 ApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/a_hello/applicationContext.xml");
 // 从容器中获取bean
 User user = (User) ac.getBean("user");
 
 System.out.println(user);
 }
}
3.2.3.bean对象创建的细节
1) 对象创建: 单例/多例
* scope="singleton", 默认值, 即 默认是单例 【service/dao/工具类】
*  scope="prototype", 多例; 【Action对象】
* 
* 2) 什么时候创建?
*   scope="prototype"  在用到对象的时候,才创建对象。
*    scope="singleton"  在启动(容器初始化之前), 就已经创建了bean,且整个应用只有一个。
* 3)是否延迟创建
*   lazy-init="false"  默认为false,  不延迟创建,即在启动时候就创建对象
*   lazy-init="true"   延迟初始化, 在用到对象的时候才创建对象
*    (只对单例有效)
* 4) 创建对象之后,初始化/销毁
*   init-method="init_user"       【对应对象的init_user方法,在对象创建爱之后执行 】
*    destroy-method="destroy_user"  【在调用容器对象的destriy方法时候执行,(容器用实现类)】
*/
@Test
**public** **void** testIOC() **throws** Exception {
// 得到IOC容器对象  【用实现类,因为要调用销毁的方法】
ClassPathXmlApplicationContext ac = **new** ClassPathXmlApplicationContext("cn/itcast/a_hello/applicationContext.xml");
System.*out*.println("-----容器创建-----");

// 从容器中获取bean
User user1 = (User) ac.getBean("user");
User user2 = (User) ac.getBean("user");

System.*out*.println(user1);
System.*out*.println(user2);

// 销毁容器对象 
ac.destroy();
}

User.java

package cn.itcast.a_hello;

public class User {

 private int id;
 private String name;
 public User() {
 super();
 System.out.println("------User对象创建------");
 }
 public int getId() {
 return id;
 }
 public void setId(int id) {
 this.id = id;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 
 public void init_user() {
 System.out.println("创建对象之后,初始化");
 }
 public void destroy_user() {
 System.out.println("IOC容器销毁,user对象回收!");
 }
 
}
3.2.4.SpringIOC容器

SpringIOS容器,是spring的核心内容。
作用:创建对象&处理对象的依赖关系。
容器创建对象:

  • 调用无参数构造器
  • 带参数的构造器
  • 工厂创建对象(工厂类的静态方法创建对象,工厂类的非静态方法创建对象
<?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:p=*"http://www.springframework.org/schema/p"*
    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"*>
<!-- ###############对象创建############### -->
<!-- 1. 默认无参数构造器 
<bean id="user1" class="cn.itcast.b_create_obj.User"></bean>
-->
<!-- 2. 带参数构造器 -->
<bean id=*"user2"* class=*"cn.itcast.b_create_obj.User"*>
<constructor-arg index=*"0"* type=*"int"* value=*"100"*></constructor-arg>
<constructor-arg index=*"1"* type=*"java.lang.String"* value=*"Jack"*></constructor-arg>
</bean>
<!-- 定义一个字符串,值是"Jack" ;  String s = new String("jack")-->
<bean id=*"str"* class=*"java.lang.String"*>
<constructor-arg value=*"Jacks"*></constructor-arg>
</bean>
<bean id=*"user3"* class=*"cn.itcast.b_create_obj.User"*>
<constructor-arg index=*"0"* type=*"int"* value=*"100"*></constructor-arg>
<constructor-arg index=*"1"* type=*"java.lang.String"* ref=*"str"*></constructor-arg>
</bean>
<!-- 3. 工厂类创建对象 -->
<!-- # 3.1 工厂类,实例方法 -->
<!-- 先创建工厂 -->
<bean id=*"factory"* class=*"cn.itcast.b_create_obj.ObjectFactory"*></bean>
<!-- 在创建user对象,用factory方的实例方法 -->
<bean id=*"user4"* factory-bean=*"factory"* factory-method=*"getInstance"*></bean>
<!-- # 3.2 工厂类: 静态方法 -->
<!-- 
class 指定的就是工厂类型
factory-method  一定是工厂里面的“静态方法”
-->
<bean id=*"user"* class=*"cn.itcast.b_create_obj.ObjectFactory"* factory-method=*"getStaticInstance"*></bean>
</beans>      

3.3.对象依赖关系

Spring中,如何给对象的属性赋值?【DI,依赖注入,根据自己的依赖关系,去写相关的bean.xml文件】

  • 通过构造函数
  • 通过set方法给属性注入值(推荐使用,还有一种是内部bean的形式,当只有一个action的时候,可以使用)
这里面包含了 ,Dao,service ,action之间的数据流程关系
<!-- dao instance -->
<bean id=*"userDao"* class=*"cn.itcast.c_property.UserDao"*></bean>
<!-- service instance -->
<bean id=*"userService"* class=*"cn.itcast.c_property.UserService"*>
<property name=*"userDao"* ref=*"userDao"*></property> 会直接调用set方法    <!—- 为什么这么写呢,因为这里在service中要用Dao的对象,所以为了解决空指针的问题,
必须先生成对象,这里不能使用value,所以要用上面的userDao—->
</bean>
<!-- action instance -->
<bean id=*"userAction"* class=*"cn.itcast.c_property.UserAction"*>
<property name=*"userService"* ref=*"userService"*></property>  和上面同理
</bean>
  • 内部bean的用法
<!-- ##############内部bean############## -->
<bean id=*"userAction"* class=*"cn.itcast.c_property.UserAction"*>
<property name=*"userService"*>
<bean class=*"cn.itcast.c_property.UserService"*>
<property name=*"userDao"*>
<bean class=*"cn.itcast.c_property.UserDao"*></bean>
</property>
</bean>
</property>
</bean>
  • p名称空间(给对象属性注入值,也可以使用p名称空间给对象的属性注入值,在spring3.0以上的版本才支持)
<?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:p=*"http://www.springframework.org/schema/p"*
    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"*>
<!-- ###############对象属性赋值############### -->
<!-- 
给对象属性注入值:
# p 名称空间给对象的属性注入值
(spring3.0以上版本才支持)
-->
<bean id=*"userDao"* class=*"cn.itcast.c_property.UserDao"*></bean>
<bean id=*"userService"* class=*"cn.itcast.c_property.UserService"* p:userDao-ref=*"userDao"*></bean>
<bean id=*"userAction"* class=*"cn.itcast.c_property.UserAction"* p:userService-ref=*"userService"*></bean>
<!-- 传统的注入: 
<bean id="user" class="cn.itcast.c_property.User" >
<property name="name" value="xxx"></property>
</bean>
-->
<!-- p名称空间优化后 -->
<bean id=*"user"* class=*"cn.itcast.c_property.User"* p:name=*"Jack0001"*></bean>
</beans>   
  • 自动装配(了解,其实各个对象都是放在容器之中。)
自动去IOC容器中找与属性名同名的引用的对象,并自动注入
<!-- ###############自动装配############### --> 
<bean id="userDao" class="cn.itcast.d_auto.UserDao"></bean>
<bean id="userService" class="cn.itcast.d_auto.UserService" autowire="byName"></bean>
<!-- 根据“名称”自动装配: userAction注入的属性,会去ioc容器中自动查找与属性同名的对象 -->
<bean id="userAction" 
class="cn.itcast.d_auto.UserAction" autowire="byName"></bean>
也可以定义到全局, 这样就不用每个bean节点都去写autowire=”byName”
<?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:p="http://www.springframework.org/schema/p"
 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" default-autowire="byName"> 根据名称自动装配(全局)
<!-- ###############自动装配############### --> 
<bean id="userDao" class="cn.itcast.d_auto.UserDao"></bean>
<bean id="userService" class="cn.itcast.d_auto.UserService"></bean>
<bean id="userAction" class="cn.itcast.d_auto.UserAction"></bean>
</beans> 
根据类型自动装配:autowire="byType"
必须确保改类型在IOC容器中只有一个对象;否则报错。
<?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:p="http://www.springframework.org/schema/p"
 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" default-autowire="byType">
<!-- ###############自动装配############### --> 
<bean id="userDao" class="cn.itcast.d_auto.UserDao"></bean>
<bean id="userService" class="cn.itcast.d_auto.UserService"></bean>
<!-- 如果根据类型自动装配: 必须确保IOC容器中只有一个该类型的对象 -->
<bean id="userAction" class="cn.itcast.d_auto.UserAction"></bean>
<!-- 报错: 因为上面已经有一个该类型的对象,且使用了根据类型自动装配
<bean id="userService_test" class="cn.itcast.d_auto.UserService" autowire="byType"></bean>
</beans> 
总结:
Spring提供的自动装配主要是为了简化配置; 但是不利于后期的维护。
(一般不推荐使用)
  • 注解(主要的目的是为了简化配置)
    注解的方式可以简化spring的IOC容器的配置。
  • 使用注解的流程
  • 1.先引入context名称空间 xmlns:context="http://www.springframework.org/schema/context"
  • 2.在bean.xml文件中开启注解扫描<context:component-scan base-package="cn.itcast.e_anno2"></context:component-scan>
  • 3.使用注解

package cn.itcast.e_anno;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

@Component("userService")  // userService加入ioc容器,对象就写Component
public class UserService {
 
 // 会从IOC容器中找userDao对象,注入到当前字段
 /*
  * <bean id="" class=""> 
  *   <property name="userDao" ref="userDao" />    @Resource相当于这里的配置,属性就写Resource
  * </bean>
  */
 
 @Resource(name = "userDao")
 private UserDao userDao;
 
 public void setUserDao(UserDao userDao) {
 this.userDao = userDao;
 }

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

注意:

创建对象以及处理对象依赖关系,相关的注解:
@Component 指定把一个对象加入IOC容器(包含了下面的三个)
@Repository 作用同@Component; 在持久层使用
@Service 作用同@Component; 在业务逻辑层使用
@Controller 作用同@Component; 在控制层使用
@Resource 属性注入

总结:

  • 使用注解,可以简化配置,且可以把对象加入IOC容器,及处理依赖关系(DI)
  • 注解可以和xml配置一起使用。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 文章作者:Tyan博客:noahsnail.com 3.4 Dependencies A typical ente...
    SnailTyan阅读 4,128评论 2 7
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • Spring 概述 什么是spring? Spring 是个java企业级应用的开源开发框架。Spring主要用来...
    Bugtags阅读 3,432评论 4 192
  • 我已不在年轻,说老又尚早,言年轻又受人呲笑。肩膀担子沉沉,父母的衣食健康,儿女的学业生活。叹一口气,睁眼把班上,挣...
    妞ye快乐阅读 442评论 0 2
  • 《马男波杰克》是一部走心的动画片,也许你会觉得是一部喜剧,实际上这是一部致郁系的动画,看完甚至不禁开始怀疑自己的人...
    Dankris阅读 2,577评论 0 1