Spring的学习1

Spring简介

  • Spring 春天 给软件行业带来了春天

  • 2002年,首次推出Spring框架的雏形:interface21框架

  • Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日,发布了1.0正式版

  • Rod Johnson,Spring Framework创始人,著名作者。很难想象Rod Johnson的学历,真的让好多人大吃一惊,他是悉尼大学的博士,然而他的专业也不是计算机,而是音乐学。

  • spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架

  • SSH : Struct2 + Spring + Hiberanate

  • SSM : SpringMVC + Spring + Mybatis

Spring 优点

  • Spring是一个开源的免费的框架
  • Spring是一个轻量级、非入侵式的框架
  • 控制反转(IOC) , 面向切面编程(AOP)
  • 支持事务的处理,对框架整合的支持

Spring 就是一个轻量级的控制反转和面向切面编程的框架!

Spring组成

在这里插入图片描述

扩展

在Sping的官网有这个介绍:现代化的Java开发!说白就是基于Spring的开发
在这里插入图片描述

Spring Boot

  • 一个快速开发的脚手架
  • 基于SpringBoot可以快速的开发单个微服务
  • 约定大于配置
    SpringCloud
  • SpringCloud是基于SpringBoot实现的

弊端:发展了太久,违背了原本的理念!配置十分繁琐,人称:“配置地狱”

IOC理论推导

利用set进行动态实现值的注入

  • 之前,程序是主动创建对象!控制权在程序员手上
  • 使用set注入后,程序不再具有主动性,而是变成了被动的接受对象

这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建了。系统的耦合性大大降低,可以更加专注的在业务的实现上!这是IOC的原型!

控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的.
反转:程序本身不创建对象,而变成被动的接收对象.依赖注入:就是利用set方法来进行注入的.
IOC是一种编程思想,由主动的编程变成被动的接收.
可以通过newClassPathXmlApplicationContext去浏览一下底层源码.
OK,到了现在,我们彻底不用再程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的loC,一句话搞定:对象由Spring来创建,管理,装配!

IOC创建对象的方式

1.使用无参构造创建对象,默认!
2.假设我们要使用有参构造创建对象。

  • 下标赋值
<bean id="user1" class="com.guantengyun.entity.User">
		<constructor-arg index="0" value="张三"/>
</bean>
  • 类型赋值(不建议使用)
 <bean id="user2" class="com.guantengyun.entity.User">
		<constructor-arg type="java.lang.String" value="张三"/>
</bean> 
  • 参数名赋值(常用)
<bean id="user3" class="com.guantengyun.entity.User">
		<constructor-arg name="name" value="lisi"/>
</bean>

总结:在配置文件加载的时候,容器中管理的对象就已经初始化了。

Spring配置

别名

<!-- 别名,如果添加了别名,也可以使用别名获取到这个对象 -->
<alias name="user1" alias="userNew"/>

Bean的配置

<!-- 
		id:bean的唯一标识符,也就是相当于我们学的对象名
		class:bean 对象的全限定名 : 包名+类名
		name : 也是别名,而且name可以同时取多个别名 ,可以以空格、逗号、分号隔开
		scope默认为单例
	 -->
<bean id="user1" class="com.guantengyun.entity.User" name="u1 uu1,uuu1;uuuu1">
		<constructor-arg index="0" value="张三"></constructor-arg>
</bean>

import

这个import,一般用于团队开发使用,可以将多个配置文件,导入合并为一个。

假设,现在项目中有多个人开发,这三个人复制不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的applicationContext.xml合并为一个总的!

<import resource="applicationContext2.xml"/>
<import resource="applicationContext3.xml"/>
<import resource="applicationContext4.xml"/>

使用的时候,直接使用总的配置就可以了

依赖注入

构造器注入

前面说过了

set方式注入【重点】

依赖注入:set注入!

  • 依赖:bean对象的创建依赖于容器
  • 注入:bean对象中的属性,由容器来注入!

    1.创建实体类(学生类和地址类)

package com.guantengyun.entity;
//地址类
public class Address {
	private String name;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "Address [name=" + name + "]";
	}
}

package com.guantengyun.entity;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
//学生类
public class Student {
	private String name;
	private Address address;
	private String[] books;
	private List<String> hobbys;
	private Map<String, String> card;
	private Set<String> games;
	private String wife;
	private Properties info;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}
	public String[] getBooks() {
		return books;
	}
	public void setBooks(String[] books) {
		this.books = books;
	}
	public List<String> getHobbys() {
		return hobbys;
	}
	public void setHobbys(List<String> hobbys) {
		this.hobbys = hobbys;
	}
	public Map<String, String> getCard() {
		return card;
	}
	public void setCard(Map<String, String> card) {
		this.card = card;
	}
	public Set<String> getGames() {
		return games;
	}
	public void setGames(Set<String> games) {
		this.games = games;
	}
	public String getWife() {
		return wife;
	}
	public void setWife(String wife) {
		this.wife = wife;
	}
	public Properties getInfo() {
		return info;
	}
	public void setInfo(Properties info) {
		this.info = info;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", address=" + address + ", books=" + Arrays.toString(books) + ", hobbys="
				+ hobbys + ", card=" + card + ", games=" + games + ", wife=" + wife + ", info=" + info + "]";
	}
}

2.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-4.3.xsd"> 
	
	
	<bean id="address" class="com.guantengyun.entity.Address">
		<property name="name" value="北京"></property>
	</bean>
	
	<bean id="student" class="com.guantengyun.entity.Student">
		<!-- 第一种,普通值注入,value -->
		<property name="name" value="管腾运"></property>
		<!-- 第二种,Bean注入,ref -->
		<property name="address" ref="address"></property>
		<!-- 数组 -->
		<property name="books">
			<array>
				<value>红楼梦</value>
				<value>西游记</value>
				<value>水浒传</value>
				<value>三国演义</value>
			</array>
		</property>
		<!-- list -->
		<property name="hobbys">
			<list>
				<value>听歌</value>
				<value>敲代码</value>
				<value>看电影</value>
			</list>
		</property>
		<!-- Map -->
		<property name="card">
			<map>
				<entry key="身份证" value="12312312312312312332"></entry>
				<entry key="银行卡" value="1111111111111111111111"></entry>
			</map>
		</property>
		<!-- Set -->
		<property name="games">
			<set>
				<value>王者荣耀</value>
				<value>刺激战场</value>
			</set>
		</property>
		<!-- NULL -->
		<property name="wife">
			<null/>
		</property>
		<!-- properties -->
		<property name="info">
			<props>
				<prop key="driver">18605182710</prop>
				<prop key="url"></prop>
				<prop key="username">root</prop>
				<prop key="password">root</prop>
			</props>
		</property>
	</bean>
</beans>

3.测试类

package com.guantengyun.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.guantengyun.entity.Student;
public class MyTest {
	@Test
	public void test1() {
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		Student student = (Student) context.getBean("student");
		System.out.println(student);
	}
}

4.结果

Student [name=管腾运, address=Address [name=北京], books=[红楼梦, 西游记, 水浒传, 三国演义], hobbys=[听歌, 敲代码, 看电影], card={身份证=12312312312312312332, 银行卡=1111111111111111111111}, games=[王者荣耀, 刺激战场], wife=null, info={url=男, password=root, driver=18605182710, username=root}]

拓展方式注入

我们可以使用p命名空间和c命名空间进行注入

<?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:c="http://www.springframework.org/schema/c"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"> 
	
	<!-- p命名空间注入,可以直接注入属性的值:property -->
	<bean id="user" class="com.guantengyun.entity.User" p:name="张三"  p:age="18"/>
	
	<!-- c命名空间注入,通过构造器注入:consturct-args -->
	<bean id="user2" class="com.guantengyun.entity.User" c:name="李四"  c:age="22"/>
</beans>

注意点:p命名和c命名不能直接使用,需要导入xml约束!

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

bean的作用域

在这里插入图片描述
1.单例模式(Spring默认机制)

<bean id="user2" class="com.guantengyun.entity.User" c:name="李四"  c:age="22" scope="singleton"/>

2.原型模式:每次从容器中get的时候,都会产生一个新的对象

<bean id="user3" class="com.guantengyun.entity.User" c:name="李四"  c:age="22" scope="prototype"/>

3.其余的request、session、application、这些个只能在web开发中使用到

Bean的自动装配

  • 自动装配是Spring满足bean依赖一种方式!
  • Spring会在上下文中自动寻找,并自动给bean装配属性!
    在Spring中有三种装配的方式
    1.在xml中显示的配置
    2.在java中显示配置
    3.隐式的自动装配bean [重要]

测试

环境搭建:一个人有两个宠物!

ByName自动装配

	<bean id="cat" class="com.guantengyun.entity.Cat"></bean>
	<bean id="dog" class="com.guantengyun.entity.Dog"></bean>
	<!-- 
		byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid
	-->
	<bean id="people" class="com.guantengyun.entity.People" autowire="byName">
		<property name="name" value="小慌神"></property>
	</bean>

ByType自动装配

	<bean  class="com.guantengyun.entity.Cat"></bean>
	<bean  class="com.guantengyun.entity.Dog"></bean>
	<!-- 
		byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean
	-->
	<bean id="people2" class="com.guantengyun.entity.People" autowire="byType">
		<property name="name" value="小慌神"></property>
	</bean>

小结:

  • ByName的时候,需要保证所有的bean的id唯一,并且这个bean需要和自动注入的属性的set方法一致!
  • ByType的时候,需要保证所有的bean的Class唯一,并且这个bean需要和自动注入的属性的类型一致!

使用注解实现自动装配

jdk1.5支持的注解,Spring 2.5支持的注解
要使用注解须知:
1、导入约束。context约束
2. 配置注解的支持 : context:annotation-config/

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:context="http://www.springframework.org/schema/context"
	   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-4.3.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-4.3.xsd">
	
	
	<!-- 开启注解的支持 -->
	<context:annotation-config />
	
	<bean id="cat" class="com.guantengyun.entity.Cat"></bean>
	<bean id="dog" class="com.guantengyun.entity.Dog"></bean>
	<bean id="people" class="com.guantengyun.entity.People"></bean>
	
</beans>

@Autowried
直接在属性上使用即可!也可以在set方法上使用!
使用Autowired我们可以不用编写set方法了,前提是这个自动装配的属性在IOC(Spring)中存在 ,且符合名字byname!
科普:

@Nullable  //字段标记了这个注解,说明这个字段可以为null
public @interface Autowired{
	boolean required() default true;
}

测试代码

public class People{
	//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
	@Autowired(required=false)
	private Cat cat;
	@Autowired
	private Dog dog;
	private String name;
}

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value=“xxx”)去配合@Autowired的使用,指定一个唯一的bean对象注入!

@Resource注解

@Resource(name="xxx") //通过name属性指定唯一的bean对象

小结:
@Autowired 和 @Resource区别:

  • 都是用来自动装配的,都可以放在属性字段上
  • @Autowired 通过bytype方式实现,而且必须要求这个对象存在!
  • @Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现,如果两个都找不到的情况下,就报错
  • 执行顺序不同

使用注解开发

在Spring4之后,要使用注解开发,必须要保证aop的包导入了
使用注解需要导入context约束,增加注解的支持!
1、bean
@Component
2、属性如何注入
@Value(“xxx”)
3、衍生的注解
@Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!

  • dao 【@Repository】
  • service【@Service】
  • controller【@Controller】
    这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean

4、自动装配
@Autowired @Qualifier
@Resource
5、作用域
@Scope(“xxx”)
6、小结
xml和注解:

  • xml更加万能,适用于任何场合!维护简单方便
  • 注解 不是自己类使用不了,维护相对复杂!

xml与注解最佳实践:

  • xml用来管理bean
  • 注解只负责完成属性的注入
  • 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持
	<!-- 开启注解的支持 -->
	<context:annotation-config />
	<!-- 指定要扫描的包,这个包下的注解就会生效 -->
	<context:component-scan base-package="com.guantengyun.entity"/>

使用Java方式配置Spring

我们现在要完全不使用Spring的xml配置了,全权交给Java来做!
JavaConfig是Spring的一个子项目,在Spring4之后,它成为了一个核心功能!
实体类

package com.guantengyun.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class User {
	@Value("管腾运")
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

配置类(配置文件)

package com.guantengyun.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import com.guantengyun.pojo.User;
//这个也会被Spring托管,注册到容器中,因为它本来就是一个@Component
//代表这是一个配置类,相当于ApplicationContext.xml
@Configuration  
@ComponentScan("com.guantengyun.pojo") //扫描包
@Import(UserConfig2.class)
public class UserConfig {
	
	//注册一个bean,相当于bean标签
	//方法的名字,相当于bean标签的id属性
	//方法的返回值,相当于bean标签的Class属性
	@Bean
	public User getUser() {
		return new User(); //就是返回要注入到bean的对象
	}
}

测试类

package com.guantengyun.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.guantengyun.config.UserConfig;
import com.guantengyun.pojo.User;

public class MyTest {
	public static void main(String[] args) {
		//如果完全使用了配置类的方式去做,我们只能通过 AnnotationConfig 上下文来获取容器,通过配置类的class对象加载!
		ApplicationContext context = new AnnotationConfigApplicationContext(UserConfig.class);
		User user = context.getBean("getUser",User.class);
		String name = user.getName();
		System.out.println("用配置类配置:"+name);
	}
}

这种纯Java的配置方式,在SpringBoot中随处可见!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值