Spring-基础

一、 概念

Spring 是一个开源框架,起源于 2003 年兴起的一个轻量级的 Java 开发框架,详细概述可参考百度百科

Spring是为了解决企业应用开发的复杂性而创建的,Spring 的核心是控制反转(IOC)和面向切面(AOP)。简单来说,Spring 是一个分层的 轻量级开源框架

相关参考文档
IOC : https://blog.csdn.net/ivan820819/article/details/79744797
软件设计六大原则 : http://www.uml.org.cn/sjms/201211023.asp#5
低耦合 : https://blog.csdn.net/ellis1970/article/details/84302912

二、优点

1、方便解耦,简化开发,Spring 就是一个大工厂,可以将所有对象创建和依赖关系维护,交给 Spring 管理
2、 AOP 编程的支持,Spring 提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
3、声明式事务的支持只需要通过配置就可以完成对事务的管理,而无需手动编程方便程序的测试,Spring 对 Junit4 支持,可以通过注解方便的测试 Spring 程序
4、方便集成各种优秀框架,Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz 等)的直接支持
5、降低 JavaEE API 的使用难度,Spring 对 JavaEE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等),都提供了封装,使这些 API 应用难度大大降低

三、Spring Framework Runtime

请添加图片描述
Core Container就是我们使用spring要导入的最最基础的包依赖

四、在IDEA中创建Spring项目

4.1 创建一个maven项目请添加图片描述

4.2 引入Spring的包依赖

<properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring.version>4.2.5.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!--Spring核心基础依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--日志相关-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!--测试相关-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--自动生成getter和setter-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
    </dependencies>

4.3 添加配置文件

配置文件的名字可以任意设置,建议设置为applicationContext.xml,所以这里我们在resource目录下创建一个名为applicationContext.xml的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"	     xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

4.4 编写相应的代码

在main的java下创建dao,model,service等层的代码

4.5 将Bean的实例化交给Spring

<!--
    通过spring管理实例和依赖
    name 依赖的名字
    class 具体依赖
    -->
<bean name="userDao" class="com.tledu.dao.impl.UserDaoImpl"/>
<bean name="userService" class="com.tledu.service.impl.UserServiceImpl">
    <!--
    注入这个属性
    name属性名,根据set方法
    ref:引用别的依赖,引用上面配置的userDao
    -->
    <property name="userDao" ref="userDao"/>
</bean>

4.6 测试

public class UserServiceTest {

    @Test
    public void add() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        // userService是bean的id或name
        UserService userService = (UserService) applicationContext
                .getBean("userService");
        userService.add(null);
    }
}

五、注入的方式

5.1 set方法注入

<bean name="userDao" class="com.tledu.dao.impl.UserDaoImpl"/>
<bean name="userService" class="com.tledu.service.impl.UserServiceImpl">
	<property name="userDao" ref="userDao"/>
</bean>

5.2 构造方法注入

<bean name="userDao" class="com.tledu.spring.dao.impl.UserDaoImpl" />
    <bean id="userService" class="com.tledu.spring.service.UserService">
        <constructor-arg ref="userDao"/>
    </bean>

5.3 普通属性注入

5.3.1 基本数据类型注入
<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl">
	<!-- 如果不是指向对象,直接用value设置值就行 -->
		<property name="daoId" value="82"></property>
		<property name="daoStatus" value="good"></property>
	</bean>
5.3.2 集合属性注入
<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl">
  <property name="lists" >
  	<list>
    	<value>1</value>
    	<value>2</value>
  	</list>
  </property>
  <property name="sets" >
  <!-- set不可重复,重复不添加,所以只有第一个三 -->
  	<set>
    	<value>3</value>
    	<value>3</value>
    	<value>5</value>
    	<value>4</value>
  	</set>
  </property>
  <property name="maps">
  <!-- mapkey不可重复,重复key不添加,value覆盖 -->
  	<map>
    	<entry key="1"  value="2"></entry>
    	<entry key="1"  value="3"></entry>
    	<entry key="2"  value="2"></entry>
  	</map>
  </property>
	</bean>

	<bean id="userService" class="com.tledu.zrz.service.UserService"
  scope="singleton">
  <!-- 构造方法注入 -->
  <constructor-arg>
  	<ref bean="userDao" />
  </constructor-arg>
	</bean>

六、Scope属性

spring中scope就是对象在spring容器(IOC容器)中的生命周期,也可以理解为对象在spring容器中的创建方式

目前,scope的取值有5种取值:
在Spring 2.0之前,有singleton和prototype两种;
在Spring 2.0之后,为支持web应用的ApplicationContext,增强另外三种request,session和global session类型。

6.1 Singleton

此取值时表明容器中创建时只存在一个实例,所有引用此bean都是单一实例。
也就是说创建对象是单例模式,并且如果不进行设置,默认就行单例

6.2 Prototype

spring容器在进行输出prototype的bean对象 时,会每次都重新生成一个新的对象给请求方,容器每次返回请求方该对象的一 个新的实例之后,就由这个对象“自生自灭”,最典型的体现就是spring与struts2进行整合时,要把action的scope改为 prototype

简单来说,就是每次获取都创建一个新对象,并且这个对象的生命周期不归Spring管理

七、自动装配(Autowire)–不需要指定注入方式

7.1 byName

byName是根据setter方法名字进行匹配,如果找不到,就不赋值
如 setUserDao 方法 就会找userDao,如果 bean的ID为 UserDao 也一样找不到,区分大小写

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl">
	</bean>
	<bean id="userService" class="com.tledu.zrz.service.UserService"  
  autowire="byName">
</bean>

7.2 byType

byType是根据setter方法的参数列表中的数据类型进行匹配,如果beans.xml中出现了多个相同类型的对象,就会报错
如 setUserDao(UserDao userDao) 方法 就会找UserDao,如果是接口,就找对应的实现类对象

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl">
	</bean>
	<bean id="userService" class="com.tledu.zrz.service.UserService"  
  autowire="byType">
</bean>

7.3 注意事项

使用自动装配,需要有公共的无参构造,虽然这里就算是私有化构造方法也依然可以创建对象,但是还是提供一个公共的比较好,万一别的框架需要呢

八、生命周期与延迟加载

8.1 生命周期

8.1.1 概念

之前servlet的生命周期
构造方法 – init – service – destroy

Spring中是没有init、service和destroy的,但是我们可以指定某个方法在创建完对象之后执行,某个方法在最后销毁的时候执行

8.1.2 实现

创建相关方法

public void init(){
  System.out.println("init--------");
	}
	public void destroy(){
  System.out.println("destroy----------");
	}
	public UserService() {
  System.out.println("service构造方法");
}

配置文件

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl" >
	</bean>
	<!--  
  init-method : 用于设置初始化的方法
  destory-method : 用于设置销毁资源的方法
  -->
	<bean id="userService" class="com.tledu.zrz.service.UserService"  
  autowire="byName"   init-method="init" destroy-method="destroy"  >
	</bean>

8.1.3 注意

Destroy之所以会执行,是因为我们默认创建对象的时候是单例模式

这个时候对象的生命周期会和Spring容器的生命周期绑定到一起,所以当我们销毁Spring容器的时候,会把所有的对象销毁,并自动调用destroy方法

但是如果我们把scope设置为prototype的时候,对象的生命周期就不会再和Spring容器绑定,销毁Spring容器的时候也就不会再执行该对象的destroy方法

scope为prototype类型时,我们容器只负责实例的创建,创建之后的生命周期由调用者负责

8.2 延迟加载

Spring容器默认是在执行
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(“beans.xml”);
进行解析的时候创建对象并调用init

如果我们不想让某个类在解析的时候就创建对象,而是用到的时候在创建对象的话,就需要设置迟加载

8.2.1 实现

创建相关方法

public UserDaoImpl(){
  System.out.println("Dao构造方法");
}
public UserService() {
  System.out.println("service构造方法");
}

配置文件

<bean name="userDao" class="com.tledu.zrz.dao.impl.UserDaoImpl" >
<bean id="userService" class="com.tledu.zrz.service.UserService"  scope="prototype"
  	autowire="byName"   init-method="init" destroy-method="destroy" lazy-init="true"  >
</bean>

通过结果可以看出,UserService的对象没有创建,只有当我们使用到这个对象的时候才会创建

我们可以在beans标签中添加default-lazy-init=“true” 对所有的bean进行迟加载

九、IOC注解

Spring框架中有注解和XML两种配置方式,包括Spring中的IOC和AOP也一样,都有XML和注解两种方式,两种注解各有优缺,但在框架中使用注解的较多

9.1 注解注入实现

9.1.1 引入依赖
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
	<version>${spring.version}</version>
</dependency>
9.1.2 配置文件中开启注解支持
<?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">
	<!-- 引入注解约束 -->
	<!-- 使用注解形式自动装配 -->
	<context:annotation-config />
</beans>

9.1.3 业务类中注解使用注解

所有需要实例化对象的类上面都加上@Component
默认是以类名首字母小写作为名字进行存储
可以使用@Component(“xxx”) 或者@Component(value=”xxx”)来设置名字

@Component
public class UserService {
    private IUserDao userDao;

    @Autowired
    public void setUserDao(IUserDao userDao) {
        this.userDao = userDao;
    }
}

9.1.4 配置扫描

在配置文件中加入内容

	<!-- 使用注解形式自动装配 -->
	<context:annotation-config />
	<!-- 使用注解形式实例化对象 -->
	<context:component-scan base-package="com.tledu.zrz" />
</beans>

9.2 Autowired注解

该注解可以加在set方法上或者直接加载属性上,如果写在setter方法上,就会通过setter方法进行注入,如果写在变量上,就直接通过反射设置变量的值,不经过setter方法。
注入时,会从spring容器中,找到一个和这个属性数据类型匹配的实例化对象注入进来,默认使用byType,根据类型匹配。
如果只能找到一个这个数据类型的对象的时候,就直接注入该对象。
如果找到了多个同一个类型的对象的时候,就会自动更改为byName来进行匹配,根据set方法对应的参数列表的局部变量名来匹配。

而@Qualifier : 可以以指定名字进行匹配

9.3 注解分类及含义

@Controller :WEB 层 ,就是和页面交互的类

@Service :业务层 ,主要处理逻辑

@Repository :持久层 ,就是Dao操作数据库

这三个注解是为了让标注类本身的用途清晰,Spring 在后续版本会对其增强

@Component: 最普通的组件,可以被注入到spring容器进行管理

@Value :用于注入普通类型. 可以写在变量上和setter方法上

@Autowired :自动装配,上面描述比较详细,可以参照上面

@Qualifier:强制使用名称注入.

@Resource 相当于: @Autowired 和@Qualifier 一起使用

@Scope: 设置对象在spring容器中的生命周期
取值 :

singleton:单例
prototype:多例

@PostConstruct :相当于 init-method

@PreDestroy :相当于 destroy-method

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值