Spring学习(一)

认识 Spring 框架

Spring 框架是 Java 应用最广的框架,它的成功来源于理念,而不是技术本身,它的理念包括 IoC (Inversion of Control,控制反转) 和 AOP(Aspect Oriented Programming,面向切面编程)。

什么是 Spring:

1.Spring 是一个轻量级的 DI / IoC 和 AOP 容器的开源框架,来源于 Rod Johnson 在其著作《Expert one on one J2EE design and development》中阐述的部分理念和原型衍生而来。
2.Spring 提倡以“最少侵入”的方式来管理应用中的代码,这意味着我们可以随时安装或者卸载 Spring
*适用范围:任何 Java 应用
*Spring 的根本使命:简化 Java 开发

耦合与解耦

什么是耦合:耦合性、。指软件系统结构中各模块间相互联系紧密程度的一种度量。模块之间联系越紧密,其耦合性就越强,模块的独立性则越差。模块间耦合高低取决于模块间接口的复杂性、调用的方式及传递的信息。
解耦:
解除类之间的直接关系,将直接关系转换成间接关系,一般情况下发现耦合需要解耦,避免强耦合,这样的话一改则全部都要改,不利于程序进行

Spring的IOC控制反转和依赖注入

控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给外部容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是组件对象的控制权转移了,从程序代码本身转移到了外部容器。
  IoC(Inversion of Control)是近年来兴起的一种思想,不仅仅是编程思想。主要是协调各组件间相互的依赖关系,同时大大提高了组件的可移植性,组件的重用机会也变得更多。在传统的实现中,由程序内部代码来控制程序之间的关系。我们经常使用new关键字来实现两对象组件间关系的组合,这种实现的方式会造成组件之间耦合(一个好的设计,不但要实现代码重用,还要将组件间关系解耦)。IoC很好的解决了该问题,它将实现组件间关系从程序内部提到外部容器来管理。也就是说由容器在运行期将组件间的某种依赖关系动态的注入到组件中。控制程序间关系的实现交给了外部的容器来完成。即常说的好莱坞原则“Don’t call us, we’ll call you”(你呆着别动,到时我会找你)。
  我们知道,如果Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。

IoC实现方法

实现控制反转主要有两种方式:依赖注入依赖查找。两者的区别在于,前者是被动的接收对象,在类A的实例创建过程中即创建了依赖的B对象,通过类型或名称来判断将不同的对象注入到不同的属性中,而后者是主动索取响应名称的对象,获得依赖对象的时间也可以在代码中自由控制。IoC的实现与语言无关。用各种语言,如C++, Java, C#等都可以。这里主要以Java为例。

依赖注入有如下实现方式:

  • 基于接口。实现特定接口以供外部容器注入所依赖类型的对象。接口中定义要注入依赖对象的方法。 基于setter方法。实现特定属性的public

  • set方法,来让外部容器调用,以传入所依赖类型的对象。如Spring Framework,WebWork/XWork。

  • 基于构造函数。实现特定参数的构造函数,在新建对象时传入所依赖类型的对象。如PicoContainer,HiveMind。

  • 基于注解。基于Java的注解功能,在私有变量前加“@Autowired”等注解,不需要显式的定义以上三种代码,便可以让外部容器传入对应的对象。该方案相当于定义了public的set方法,但是因为没有真正的set方法,从而不会为了实现依赖注入导致暴露了不该暴露的接口(因为set方法只想让容器访问来注入而并不希望其他依赖此类的对象访问)。

  • 依赖查找更加主动,在需要的时候通过调用框架提供的方法来获取对象,获取时需要提供相关的配置文件路径、key等信息来确定获取对象的状态。这主要是通过JNDI或ServiceManager等获得依赖对象
    -控制反转实现方式

依赖注入

依赖注入的基本原则是:应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应该由IoC容器负责,“查找资源”的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责。

实例:

构建一个maven工程,加入spring依赖。

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.3.13.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>${spring.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>${spring.version}</version>
</dependency>
</dependencies>

UserDao.java

package com.rimi.springtext.dao;
 
public class UserDao {
	public String get(String name) {
		return "hello,"+name;
	}
}

Userserver.java

package com.rimi.springtext.service;
package com.rimi.springtext.dao.UserDao;
public class UserService {
	private UserDao userDao;
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	public String get(String name) {
		return userDao.get(name);
	}
}

spring.xml

<bean id="userDao" class="com.rimi.springtext.dao.UserDao"></bean>
<bean id="userService" class="com.rimi.springtext.service.UserService">
    	<property name="userDao" ref="userDao"/>
</bean>

测试类

package com.rimi.springtext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.rimi.springtext.service.UserService;
public class SpringMain {
	@SuppressWarnings("resource")
	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring.xml");
		UserService userService = context.getBean(UserService.class);
		String hello = userService.get("lx");
		System.out.println(hello);
	}
}

这个演示了一个原始的spring作为一个ioc容器的例子,很简单,我们对UserDao,UserService实体做了bean配置,然后需要的时候,通过context.getBean()就可以获取了,很方便,但是随着业务的扩展,这种bean的配置会越来越多,而且bean的依赖也会做配置,这时候,注解就是用来做多编码,少做配置的。

spring注解提供了@Component、@Repository、@Service、@Controller等注解,用于配置在实体bean上,表示这是一个组件,会被spring容器扫描并实例化。

@Resource、@Autowired注解,用于配置在实体的属性上,表示这个属性可以通过依赖注入的方式给注入到实体中。这样,有了实体,有了依赖,我们就可以通过spring获取一个bean对象,并执行相关的方法。实体的实例化和依赖注入,全部通过注解来实现了,但是有一点,虽然实体bean和属性不用在xml配置文件里面配置了,但是我们还需要配置一个包扫描路径,告诉spring容器,我们的实体bean在哪里,让他去指定的包路径下扫描并实例化和注入。

因此,改过之后的spring示例,代码会是这个样子的。

UserDao.java

package com.rimi.springtext.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
	public String get(String name) {
		return "hello,"+name;
	}
}

UserService.java

package com.rimi.springtext.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.rimi.springtext.dao.UserDao;
@Service
public class UserService {
	@Autowired
	private UserDao userDao;
	public String get(String name) {
		return userDao.get(name);
	}
}

spring.xml

<context:component-scan base-package="com.rimi.springtext" />

这下子spring配置文件简单了很多,就一个配置。这里我们测试,使用单元测试,因为可以使用注解@Resource、@Autowire来做依赖注入,所以UserService不用通过context.getBean()的方式来获取了。
test.java

package com.rimi.springtext;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.rimi.springtext.service.UserService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"classpath:spring.xml"})
public class Test1 {
	@Resource
	private UserService userService;
	@Test
	public void test2() {
		String name = "lx";
		String res = userService.get(name);
		System.out.println(res);
	}
}

这个实例里面,我们对UserDao,UserService实体采用了@Repository,@Service注解,表示这是一个实体bean,我们可以考虑去掉这些注解,同样可以实现实体bean的实例化,就是xml配置需要做一些修改。
UserDao.java

package com.rimi.springtext.dao;
public class UserDao {
	public String get(String name) {
		return "hello,"+name;
	}
}

UserService.java

package com.rimi.springtext.service;
import org.springframework.beans.factory.annotation.Autowired;
import com.rimi.springtext.dao.UserDao;
public class UserService {
	@Autowired
	private UserDao userDao;
	public String get(String name) {
		return userDao.get(name);
	}
}

spring.xml

<context:component-scan base-package="com.rimi.springtext">
       <context:include-filter type="regex" expression="com\.rimi\.springtext\.dao\..*"/>
       <context:include-filter type="regex" expression="com\.rimi\.springtext\.service\..*"/>
</context:component-scan>

对于扫描包配置,我们做进一步细化,使用context:include-filter来指定了具体的包下面的所有实体。这样我们的实体bean上就不需要设置注解了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值