Sping 的简介
Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。
Spring的特点
1.Spring是一个开源的免费框架(容器)
2.Spring是一个轻量级、非入侵式的框架
3.控制反转(IOC)面向切面编程(AOP)核心
4.支持事务的处理,对框架整合
使用Spring
我们在maven的项目中只需要导入spring-webmvc架包,maven会自动为我们导入其他的依赖架包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
Sping的七大核心模块
核心容器(Spring Core)
核心容器提供Spring框架的基本功能。Spring以bean的方式组织和管理Java应用中的各个组件及其关系。Spring使用BeanFactory来产生和管理Bean,它是工厂模式的实现。BeanFactory使用控制反转(IoC)模式将应用的配置和依赖性规范与实际的应用程序代码分开。
应用上下文(Spring Context)
Spring上下文是一个配置文件,向Spring框架提供上下文信息。Spring上下文包括企业服务,如JNDI、EJB、电子邮件、国际化、校验和调度功能。
Spring面向切面编程(Spring AOP)
通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring框架中。所以,可以很容易地使 Spring框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
JDBC和DAO模块(Spring DAO)
JDBC、DAO的抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理,和不同数据库供应商所抛出的错误信息。异常层次结构简化了错误处理,并且极大的降低了需要编写的代码数量,比如打开和关闭链接。
对象实体映射(Spring ORM)
Spring框架插入了若干个ORM框架,从而提供了ORM对象的关系工具,其中包括了Hibernate、JDO和 IBatis SQL Map等,所有这些都遵从Spring的通用事物和DAO异常层次结构。
Web模块(Spring Web)
Web上下文模块建立在应用程序上下文模块之上,为基于web的应用程序提供了上下文。所以Spring框架支持与Struts集成,web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
MVC模块(Spring Web MVC)
MVC框架是一个全功能的构建Web应用程序的MVC实现。通过策略接口,MVC框架变成为高度可配置的。MVC容纳了大量视图技术,其中包括JSP、POI等,模型来有JavaBean来构成,存放于m当中,而视图是一个街口,负责实现模型,控制器表示逻辑代码,由c的事情。Spring框架的功能可以用在任何J2EE服务器当中,大多数功能也适用于不受管理的环境。Spring的核心要点就是支持不绑定到特定J2EE服务的可重用业务和数据的访问的对象,毫无疑问这样的对象可以在不同的J2EE环境,独立应用程序和测试环境之间重用。
Sping三大核心思想
DI(依赖注入) :后台需要对象时,spring容器将给后台空对象以bean的方 式注入对象
IOC(控制反转) :后台对象由主动创建变被动接受,权限发生了转移
AOP(面向切面编程):在整个系统中,动态横向添加新的功能,还不改变原来业务流程的编码。 那么横向扩展怎么理解呢,我们在WEB项目开发中,通常都遵守三层原则:
包括控制层(Controller)->业务层(Service)->数据层(dao),那么从这个结构下来的为纵向,它具体的某一层就是我们所说的横向。(AOP是OOP的补充)
IOC创建对象
创建Spring的xml配置applicationContext.xml
可以参考官方文档Sping官方文档
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
Hello.java
package com.zx.hello;
/**
* @Author Tim
* @Date 2020/7/22 22:43
* @Version 1.0
*/
public class Hello {
private String hello;
public String getHello() {
return hello;
}
//set方法在这里是什么关键的(由set方法来注入对象的),没有Set方法就会报错
public void setHello(String hello) {
this.hello = hello;
}
@Override
public String toString() {
return "Hello{" +
"hello='" + hello + '\'' +
'}';
}
}
以前创建对象:
Hello hello = new Hello();
现在在Sping配置文件中(前提是要保证Hello这个类必须存在):
id = 变量名 – hello
class = new Hello();
bean = 对象
property = 对象属性值
<?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">
<!--使用Spring来创建对象,在Spring中统一叫做Bean-->
<!-- 该id属性是标识单个bean定义的字符串。
该class属性定义Bean的类型,并使用完全限定的类名。
该id属性的值是指协作对象。在此示例中未显示用于引用协作对象的XML
-->
<!--
bean = 对象
Hello hello = new Hello();
id = 变量名
class = new 的对象
property 相当于给对象中的属性设值
-->
<bean id="hello" class="com.zx.hello.Hello">
<!--给对象属性设值-->
<property name="hello" value="spring"></property>
<!-- collaborators and configuration for this bean go here -->
<!--ref是引用Spring容器中创建好的对象-->
<!--<property name="xx" ref="conversionService"></property>-->
</bean>
</beans>
然后便可以在Java实现类中调用对象(sping 容器一加载对象就创建了)
//获取Spring上下对象(获取Spring容器)
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
//到此我们的对象就在Spring中管理了,我们要使用就直接去拿就好了。
Hello hello = (Hello) ac.getBean("hello");
Hello hello = ac.getBean("hello",Hello.class);
IOC创建对象的方式
使用无参构造创建对象(默认)
使用有参构造创建对象(如下)
<bean id="user1" class="com.zx.user.Users">
<!--index对象属性下标 下标赋值-->
<constructor-arg index="0" value="李四"></constructor-arg>
</bean>
<!-- 不建议使用 当有多个相同类型就went 类型-->
<bean id="user2" class="com.zx.user.Users">
<constructor-arg type="java.lang.String" value="王五"></constructor-arg>
</bean>
<!-- 直接通过参数名-->
<bean id="user3" class="com.zx.user.Users">
<constructor-arg name="name" value="董彬"></constructor-arg>
</bean>
DI(依赖注入)
依赖:bean对象的创建依赖于容器
注入:bean对象中的所有属性值由容器注入
1.构造器注入(前面)
2.set注入(重点)
<?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">
<bean id="home" class="com.zx.Home">
<property name="home" value="安徽宣城"></property>
</bean>
<bean id="student" class="com.zx.Student">
<property name="name" value="黄杰"></property>
<property name="home" ref="home"/>
<property name="books">
<array>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
<value>红楼梦</value>
</array>
</property>
<property name="hobbys">
<list>
<value>多人运动</value>
<value>篮球</value>
</list>
</property>
<property name="cards">
<map>
<entry key="身份证" value="111111111111"></entry>
<entry key="银行卡" value="23456s"></entry>
</map>
</property>
<property name="games">
<set>
<value>王者荣耀</value>
<value>刺激战场</value>
</set>
</property>
<property name="info">
<props>
<prop key="学号">16014420048</prop>
<prop key="姓名">大黄</prop>
</props>
</property>
<property name="wrok">
<null></null>
</property>
</bean>
</beans>
3.其他注入
<?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.xsd">
<!--需要在USER类里添加无参构造器
p命名空间对应就是set的属性注入property
-->
<bean id="user1" class="com.obj.User" p:name="张三" p:age="18" scope="prototype"></bean>
<!--需要在USER类里添加有参构造器
c命名空间对应就是构造器注入-->
<bean id="user2" class="com.obj.User" c:name="李四" c:age="20"></bean>
<!--p 和 c命名空间不可以直接使用,要导入XML约束-->
<!--scope作用域,bean的作用域 默认是单例模式singleton 原型模式prototype
其余的在Web开发使用request、session、application
-->
</beans>
p 和 c命名空间不可以直接使用,要导入XML约束
<!--scope作用域,bean的作用域 默认是单例模式singleton 原型模式prototype
其余的在Web开发使用request、session、application
-->
IOC的本质
IOC(控制反转),他是一中设计思想!IOC的本质就是获得依赖对象的方式反转了,使程序不要再去管理对象的创建,使得程序的耦合大大降低,可以将对象的创建交给第三方。
控制反转就是通过描述(xml配置文件、注解)通过第三方去产生或者获取到对象的方式,在Sping中IOC容器实现了控制反转,其实现的方法便是DI(依赖注入)。
补充(自动装配)
Bean的自动装配
自动装配是Spring是满足bean依赖的一种方式,Sping会在上下文中自动寻找,并自动给bean装配属 性。spring中有三种装配方式:
1.xml中显示配置
2.在java中显示配置
3.隐式的自动装配(***)
方式一:
<?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">
<bean id="cat" class="com.zx.Cat">
<property name="name" value="猫因"/>
</bean>
<bean id="dog" class="com.zx.Dog">
<constructor-arg name="name" value="豆豆"/>
</bean>
<bean id="people" class="com.zx.People">
<property name="name" value="大黄"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
</bean>
<!--自动装配-->
<!-- byName 会自动在容器中寻找和自己对象set方法后面的值对应的bean id-->
<bean id="people1" class="com.zx.People" autowire="byName">
<property name="name" value="亚飞"/>
</bean>
<!-- byType 会自动在容器中寻找和自己对象类型相同的bean id-->
<bean id="people2" class="com.zx.People" autowire="byType">
<property name="name" value="董小姐"/>
</bean>
</beans>
import com.zx.People;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Author Tim
* @Date 2020/7/23 17:12
* @Version 1.0
*/
public class Test6 {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
People people = ac.getBean("people",People.class);
people.getCat().show();
people.getDog().show();
System.out.println("这个人叫"+people.getName());
People people1 = ac.getBean("people1",People.class);
people1.getCat().show();
people1.getDog().show();
System.out.println("这个人叫"+people1.getName());
People people2 = ac.getBean("people2",People.class);
people2.getCat().show();
people2.getDog().show();
System.out.println("这个人叫"+people2.getName());
}
}
方式二、
使用JAVA的方式来配置Spring
完全不用Spring的XML配置了
JavaConfig是Spring的一个子项目,在Spring4之后变为一个核心功能
@Configuration代表是一个配置``类,就和我们之前的bean.xml一样
@ComponentScan("com.zx")扫描包
@Bean//注册一个bean就相当于bean标签,方法名字就是id,返回值就是class属性
package com.config;
import com.zx.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @Author Tim
* @Date 2020/7/24 17:51
* @Version 1.0
*/
@Configuration//这个也会被容器托管,注册到容器中,因为他本就是一个@Component
@ComponentScan("com.zx")//不写也可以
public class UserConfig {
@Bean//注册一个bean就相当于bean标签,方法名字就是id,返回值就是class属性
public User getUser(){
return new User();
}
}
package com.zx;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @Author Tim
* @Date 2020/7/24 17:48
* @Version 1.0
*/
@Component
public class User {
private String name;
public String getName() {
return name;
}
@Value("张三")
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
import com.config.UserConfig;
import com.zx.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @Author Tim
* @Date 2020/7/24 17:57
* @Version 1.0
*/
public class Test9 {
public static void main(String[] args) {
//如完全使用配置方法去做,通过 AnnotationConfigApplicationContext上下文去获取容器,通过配置类的class对象加载
ApplicationContext ac = new AnnotationConfigApplicationContext(UserConfig.class);
User user = ac.getBean("getUser",User.class);
System.out.println(user.getName());
}
}
方式三、
注解实现自动装配
使用注解要开启注解支持
<context:annotation-config/>
1.@Autowired 直接在属性上使用即可或者在Set方法上使用也可以。 这个注解使用反射的方式实现的,可以不写
SET方法也是可以注入的(前提是你要自动装配的属性在IOC容器(spring)中存在 ,符合byType)如果自动装配
的环境比较复杂,可以添加@Qualifier(value = "dog111")去配合@Autowired,获取唯一值。@Autowired(required =
false)//required = false 允许在容器中为null
2.@Resource (是JDK的注解。不是Sping)
3.@Nullable
如果可以传入NULL值,则标记为@Nullable,如果不可以,则标注为@Nonnull。那么在我们做一些不安全严谨操作
的编码操作时,这些注释会给我们一些警告。
@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是
javax.annotation.Resource,但是Spring支持该注解的注入。
1、共同点
两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。
2、不同点
(1)@Autowired
@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照
byType注入。@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果
允许null值,可以设置它的required属性为false.如果我们想使用按照名称(byName)来装配,可以结合@Qualifier
注解一起使用。
(2)@Resource
@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两
个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析bean
的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策
略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
Spring注解开发
在spring4之后要使用注解开发,必须保证导入aop架包
1.使用注解要增加注解支持!(主要是开启程序的注解驱动)
<context:annotation-config/>
2.扫描机制
指定要扫描的包,这个包下的注解就会生效(Spring特定的注解)
<context:component-scan base-package="com"/>
注解(bean)
1.@Component(组件)
@Component
等价与
<bean id="user" class="com.entity.User"></bean>
2.@Value()
Spring注解注入属性值使用 @Value("大黄")
相当于
<property name="xxx" value="xxx"></property>
3.@Component的衍生注解
(1)@Repository(仓库 持久层)
(2)@Service(业务层)
(3)@Controller(控制层)
这四个注解的功能都是一样的,都是代表将某个类注册到Spring中,装配Bean
4.作用域的注解
@Scope("singleton")
package com.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import javax.annotation.Resource;
/**
* @Author Tim
* @Date 2020/7/24 14:37
* @Version 1.0
*/
public class Peope {
@Resource
private Cat cat;
@Autowired(required = false)//required = false 允许在容器中为null
@Qualifier(value = "dog111")
private Dog dog;
private String name;
public void show(){
cat.Show();
dog.show();
System.out.println("你们都是我的宠物");
}
}
package com.bean;
/**
* @Author Tim
* @Date 2020/7/24 14:30
* @Version 1.0
*/
public class Cat {
private String name;
public void Show(){
System.out.println("你好我是小猫咪");
}
}
package com.bean;
/**
* @Author Tim
* @Date 2020/7/24 14:36
* @Version 1.0
*/
public class Dog {
private String name;
public void show(){
System.out.println("我是一个汪星人");
}
}
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="cat" class="com.bean.Cat"></bean>
<bean id="dog11" class="com.bean.Dog"></bean>
<bean id="dog111" class="com.bean.Dog"></bean>
<bean id="people" class="com.bean.Peope"></bean>
<!-- 开启注解支持-->
<context:annotation-config/>
</beans>
最后
感谢你看到这里,看完有什么的不懂的可以在评论区问我,觉得文章对你有帮助的话记得给我点个赞,每天都会分享java相关技术文章或行业资讯,欢迎大家关注和转发文章!
网友评论