spring学习总结

spring学习笔记

因为本人最近刚学习完ssm,这篇当做整理思路来用,其中有不严谨的地方还请大佬指出。
因为spring涉及的内容比较多,担心自己会坚持不下去,就每天更新一些。如果对你理解
spring有所帮助那真是最好不过了。

1. spring是什么
spring是一个轻量级的、可以集成各种优秀框架的java开发框架,其核心是控制反转(ioc)和面向切面编程 (aop)。其主要作用是降低代码之间的耦合度(ioc带来的效果),提高系统的复用率以及更灵活的进行事务管理(aop带来的效果)。

2. 控制反转是什么
控制反转是一种重要思想,传统上我们使用程序来操作对象而现在我们将权限交给容器,通过容器来完成对象的创建和使用。
控制反转就是对对象控制权的转移,从程序代码本身转移到外部容器中,通过外部容器来实现对对象的创建,属性的赋值,依赖的管理。

那什么是依赖呢?
依赖:简单点可以理解为classA类有classB类的实例,通过调用classB的方法来完成功能,即A类对B类有依赖。

spring框架就是使用依赖注入(DI)来实现IOC。
这里可以把spring容器想象成一个工厂,负者创建、管理所有的java对象,这些java对象称为bean。spring容器管理着容器中的bean之间的依赖关系(依赖注入),使用IOC实现了对象的解耦合。

1. 举个栗子(第一个)
第一步,我们在java的源目录下,创建com.zxj.dao包
先定义一个接口和该接口的实现类

public interface SomeService {  void doSome(); } 
 
public class SomeServiceImpl implements SomeService { 
 public SomeServiceImpl() { 
   super(); 
   System.out.println("SomeServiceImpl无参数构造方法"); 
    }
     @Override 
      public void doSome() 
   {   System.out.println("====业务方法doSome()===");  } } 

第二步、我们在resources资源目录下创建一个spring.xml的配置文件,命名为applicationContext。接着在里面创建一个bean,这个bean的功能就是让spring容器可以为我们创建一个我们需要的实例对象。
代码如下。

<bean id="someService" class="com.zxj.dao.SomeServiceImpl" />

这个bean标签:1、class:我们想让spring容器用这个类来创建对象,其中这个类的类路径。2、id:当spring容器创建好这个对象后,我们从外部通过getBean()来获取容器中这个bean,id就是这个bean的唯一标识,具有唯一性。

第三步、创建一个测试类,来看看效果(部分代码如下)

@Test
public void test01(){
//指定spring的配置文件,并且创建spring容器
	ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
	//通过id来获取容器中该id指定的对象。
	SomeService someService = (SomeService)app.getBean("someService");
	someService.dosome();
}

这里如果按照以前的思路,需要我们手动来new,
SomeService SomeService = new SomeServiceImpl();
就像这样,但是这里我们交给了容器来做,直接从容器中来拿已经创建好的对象,
这就是控制反转。

ApplicationContext 容器会在容器对象初始化的时候,将其中所有对象一次性装配好
(说人话就是,在容器创建初始化的时候,会读取配置文件,这里我们传入的是“applicationContext.xml”,创建好这个配置文件中我们配置的bean标签所对应的对象,并且放入容器中,id为创建对象的唯一标识,供外部调取时候使用)
效果就不贴出来了,留下思考,为什么会有两个输出语句呢?

好了通过上面这个,我们已经成功通过spring容器来创建对象了,那有了对象不赋值怎么行,接下来会从多个方法来完成对对象的赋值。

1. set注入
该方式在以后是较为常用的一种,需重点照顾。
上栗子(第二个)!!!

第一步:在java的源目录下,创建com.zxj.dao包,在该包下创建一个学生类

public class Student{
	private String name;
	private Integer age;
}

第二步:在resources目录下创建spring.xml的配置文件,命名为applicationContext

<bean id="studnet" class="com.zxj.dao.Student" >
//简单属性赋值
<property name="name" value="卡特琳娜" />
<property name="age" value="18" />
</bean>

第三步:创建测试类

@Test
public void test02(){
//指定spring的配置文件,并且创建spring容器
	ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
	//通过id来获取容器中该id指定的对象。
	Student student = (Student)app.getBean("studnet");
	//输出 一下看下效果
	System.out.println(student);
}

这里一样不把效果贴出,好奇的自己动手看看。

上面这是简单类型的注入,在后面开发中常用的还有引入注入

上栗子(第三个)!!!

第一步、在上面这个例子的基础上,在dao包中添加一个新类取名School,并把School类引入到Student类中

public class School{
	private String name;
	private String address;
}
public class Student{
	private String name;
	private Integer age;
	//应用类
	private School school;
}

第二步、在applicationContext.xml配置文件中创建一个id为studnet的bean

<bean id="school" class="com.zxj.dao.School">
<property name="name" value="洛克萨斯学院" />
<property name="address" value="洛克萨斯" />
</bean>

修改之前的id为student的bean

<bean id="studnet" class="com.zxj.dao.Student" >
//简单属性赋值
<property name="name" value="卡特琳娜" />
<property name="age" value="18" />
<property name="school" ref="school" />
</bean>

第三步、运行上面例子中的测试类,看看效果。
这样我们就可以给一个类中的应用类型赋值了。其中ref指向要应用的类型的bean,也就是我们上面新创建的名为school的bean。

除了set注入以外,还有一种名为构造器注入的方式,不过不怎么常用。上栗子(第四个)!!
第一步、在dao包下创建一个新类为Student2,并且生成一个有参的构造方法

public class Student2{
	private String name;
	private Integer age;
	//应用类
	private School school;

	public  stu(String myName,Integer myAge,School mySchool){
		this.myName=myName;
		this.myAge=myAge;
		this.mySchool=mySchool;
	}
}

第二步、修改applicationContext配置文件中的id为student的bean

<bean id="studnet" class="com.zxj.dao.Student" >
//简单属性赋值
<constructor-arg name="myName" value="卡特琳娜" />
<constructor-arg name="myAge" value="18" />
<constructor-arg name="mySchool" ref="school" />
</bean>

第三步、运行测试类,看看效果。这里不会贴出运行结果!!!(以后也不会,,,,)

俗话说:不会偷懒的程序猿不是好的程序猿。当遇到应用类型的时候,我们一边要给引用类型创建一个bean,一边还有修改应用该类型的bean。太累了,诶,这里前辈们也想到了,于是 “引用类型注入” 应运而生。

引用类型自动注入,有两个方法:
1、byName(顾名思义通过名字来完成注入),
2、byType(顾名思义通过类型完成注入)。

1.1、byName.
这里可以直接修改第三个栗子,修改如下

<bean id="studnet" class="com.zxj.dao.Student" autowire="byName" >
//简单属性赋值
<property name="name" value="卡特琳娜" />
<property name="age" value="18" />
//<property name="school" ref="school" />

这样修改后,spring在加载配置文件开始创建student对象的时候,会自动搜索与student类中应用类型的变量名相同的bean的id,相匹配,完成注入赋值。在第三个栗子中,我把引用类型的变量名定义成了school这样在加载配置文件的时候,spring会搜索有没有bean的id为school,有的话就会完成自动注入。

2.1byType类型注入
这里一样在第三个栗子基础上进行理解。上修改

<bean id="studnet" class="com.zxj.dao.Student" autowire="byType" >
//简单属性赋值
<property name="name" value="卡特琳娜" />
<property name="age" value="18" />
//<property name="school" ref="school" />

这里可以看到,我们只是将byName换成了byType。顺序一样是,加载配置文件,创建student对象时候,因为我们在Student类中引入的是School类的对象,所以spring会搜找bean中有没有创建好的School的对象,完成注入。

这里比较推荐byName来完成自动注入,因为如果配置文件中有多个School对象时候spring就不知道该将哪个对象注入进去,抛出异常。

在以后的开发中难免会遇到多个配置文件的情况,这里提一下如何导入外部的配置文件。
格式如下:

<import resource="calsspath:com/zxj/dao/XXXX.xml" />

重点:基于注解的DI(基于注解完成依赖注入)
1、我们首先要知道,当我们选择基于注解的时候,就不用在spring的配置文件中声明bean的实例了。
首先我们在spring配置文件中添加一个扫描器,该扫描器会扫描路径下的代码寻找注解,进一步完成相对应的操作。扫描器代码如下。

<context:componet-scan base-package="" />

base-package里面写入的是要扫描的路径具体到包就可以了。

配置好扫描器了,那么我们就可以在代码中加入注解了。
注解1:@Componet(value=""),
value的值可以理解为bean的id。具有唯一标识。value可以省略。省略后id的值为该类的类名(首字符小写)
使用位置:在类上。
好搭档:@value;位置在属性上

@Componet(value="student")
public calss Student{
	@value("卡特琳娜")
	private	String name;
	@value("18")
	private	Integer age
}

在注解中,同样也可以进行用byType来完成DI
注解2:@Autowired,
这里先将school类加上注解

@Compoent("mySchool")
public class School{
	@value("盘龙小学")
	private String name;
	@value("云深不知处")
	private String addre
}

修改student类

@Compoent("student")
public class Student{
	@value("卡特")
	private String name;
	@value("18")
	private Ingeter age;
	@Autowried
	private School school;
}

理解同xml形式的思路

说完byType,那就不得不提起byName了。
在使用@Autowried的基础上添加了@Qualifier

@Compoent("mySchool")
public class School{
	@value("盘龙小学")
	private String name;
	@value("云深不知处")
	private String addre
@Compoent("student")
public class Student{
	@value("卡特")
	private String name;
	@value("18")
	private Ingeter age;
	@Autowried
	@Qualifier("mySchool")
	private School school;
}

细细品味一下。
同时还有基于jdk注解的@Resource使用的时候同@Autowried差不多,不过在使用byName的时候不需要使用@Qualifier,其自带name属性,

@Compoent("student")
public class Student{
	@value("卡特")
	private String name;
	@value("18")
	private Ingeter age;
	@Resource(name="mySchool"private School school;
}

来做个对比
注解优点是:
⚫ 方便
⚫ 直观
⚫ 高效(代码少,没有配置文件的书写那么复杂)。
其弊端也显而易见:以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的。

XML 方式优点是:
⚫ 配置和代码是分离的
⚫ 在 xml 中做修改,无需编译代码,只需重启服务器即可将新的配置加载。
xml 的缺点是:编写麻烦,效率低,大型项目过于复杂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值