给软件行业带来了春天——揭秘Spring究竟是何方神圣(一)
给软件行业带来了春天——揭秘Spring究竟是何方神圣(二)
给软件行业带来了春天——揭秘Spring究竟是何方神圣(三)
给软件行业带来了春天——揭秘Spring究竟是何方神圣(四)
给软件行业带来了春天——揭秘Spring究竟是何方神圣(五)
Spring是一个JavaEE开源的轻量级别的框架,可以解决我们企业开发中遇到的难题,能够让编码变的更加简单,核心组件IOC容器和Aop面向切面编程。
spring优点:
spring框架图
Spring 是模块化的。
Core 容器
Core 容器由 Core、Beans、Context 和 Expression Language 模块组成。
数据访问/集成
数据访问/集成层由 JDBC、ORM、OXM、JMS 和 Transaction 事务模块组成。
Web
Web 层由 Web、Web-MVC、Web-Socket 和 Web-Portlet 模块组成。
其他
如 AOP、Aspects、Instrumentation、Web 和 Test 模块。
Spring核心特性:
依赖注入 (DI):
Inversion of Control (IoC) 控制反转是一个通用概念,可以用多种不同的方式表达。 依赖注入只是控制反转的一个具体例子。在编写复杂的 Java 应用程序时,应用程序类应尽可能独立于其他 Java 类,以增加重用这些类的可能性,并在单元测试时独立于其他类对其进行测试。 依赖注入有助于将这些类粘合在一起,同时保持它们的独立性。
依赖注入简单来说,例如,依赖,A 类依赖于B类。注入就意味着,B 类将被 IoC 注入到 A 类中。
面向切面编程(AOP)
跨越应用程序多个点的功能称为横切关注点,这些横切关注点在概念上与应用程序的业务逻辑分开。 有各种常见的好例子,包括日志记录、声明式事务、安全性、缓存等。
OOP 中模块化的关键单元是类,而 AOP 中模块化的单元是方面。 DI 可帮助您将应用程序对象彼此分离,而 AOP 可帮助您将横切关注点与它们影响的对象分离。
面向切面是一种思想,不是具体的框架,也不是具体的代码。
更多消息可以去官方文档查看。
spring的官网:Home
Spring官方下载依赖jar包地址:JFrog
spring教程:Spring 教程
IOC(Inversion of Control) 控制反转是一种面对对象编程的设计原则,用于降低代码之间的耦合度。IOC容器主要作用就是创建对象和处理对象之间的依赖关系。
Bean的管理
每次单独new对象,没有实现统一管理对象,如果后期userDao的名称信息发生变化的情况下,需要改变的引用地方比较多,耦合度太高。
概念:统一的管理和维护我们每个对象创建与使用的过程。
不需要自己new对象。
降低代码的-耦合度
反射创建对象
public class Fast {
public Fast() {
System.out.println("spring创建对象方式一:通过无参构造方法");
}
}
@Test
public void test01(){
ApplicationContext applicationContext=
new ClassPathXmlApplicationContext("bean.xml");
}
public class Slow {
private Integer id;
private String name;
public Slow(Integer id,String name){
//super();
this.id = id;
this.name = name;
System.out.println("spring创建对象方式2:通过有参构造方法"+"\n"+id+"-"+name);
}
}
@Test
public void test01(){
ApplicationContext applicationContext=
new ClassPathXmlApplicationContext("bean.xml");
}
通过调用类的静态工厂方法来创建对象
public class Fast {
public Fast() {
System.out.println("spring创建对象第3种方式:通过静态方法工厂创建");
}
}
public class FastFactory {
public static Fast getInstance(){
System.out.println("通过静态方法工厂创建对象");
return new Fast();
//相当于Fast.getInstance();
}
}
@Test
public void test01(){
ApplicationContext applicationContext=
new ClassPathXmlApplicationContext("bean.xml");
}
调用对象的实例方法来创建对象
public class cost {
public cost(){
System.out.println("通过实例工厂创建对象");
}
}
public class costFactory {
public cost getInstance(){
return new cost();
}
}
@Test
public void test01(){
ApplicationContext applicationContext=
new ClassPathXmlApplicationContext("bean.xml");
}
public class messageBean {
public messageBean(){
System.out.println("通过实现FactoryBean接口实现对象的创建");
}
}
public class bean implements FactoryBean {
@Override
public messageBean getObject() throws Exception {
return null;
}
@Override
public Class> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return true;
}
}
@Test
public void test01(){
ApplicationContext applicationContext=
new ClassPathXmlApplicationContext("applicationContext.xml");
messageBean bean=applicationContext.getBean("factotybean", messageBean.class);
}
spring容器通过调用对象提供的set方法或者构造器来建立依赖关系。
依赖关系的创建流程
spring 容器启动后读取配置文件
在Bean标签下 在定义一个属性<property>标签
属性值包含特殊符号
1 把<>进行转义 < >
2 把带特殊符号内容写到CDATA
>]]>
>]]>
-->
//注入属性 外部bean
public class db {
private IB di;
private String name;
public void setName(String name) {
this.name = name;
}
public void setDi(IB di) {
this.di = di;
System.out.println("调用了方法");
}
}
public class di implements IB{
private String diname;
public di(){
}
public void setDiname(String diname) {
this.diname = diname;
}
public void f1(){
System.out.println("注入bean的属性");
}
}
/*test01
测试set方式的注入
* */
@Test
public void test01(){
db db=abstractApplicationContext.getBean("db1",ioc.db.class);
logger.info("依赖注入成功。");
}
注入属性—外部bean
//注入属性 外部bean
注入属性—内部bean
//注入属性---内部bean
在Bean标签下 在定义一个属性**标签**
constructor-arg 元素:构造器方式注入
name 指定参数列表名称_,_** **index 指定参数列表索引,参数的下标(从0 开始)
public class A {
private B b;
public A(){
System.out.println("A");
}
public A(B b){
System.out.println("构造器方式注入");
this.b=b;
}
public void execute(){
System.out.println("成功注入");
b.f1();
}
}
public class B {
public B(){
System.out.println("对象被创建");
}
public void execute(){
System.out.println("execute");
}
public void f1(){
System.out.println("被成功注入");
}
}
/*
* 构造器注入
* */
@Test
public void test01(){
A a1=applicationContext.getBean("a1",A.class);
a1.execute();
logger.info("构造器方式注入完成");
}
Xml头部引入P标签:
使用p标签注入属性:
p名称注入也是调用了set 方法注入属性。
public class stu {
//四种类型属性
private String[] courses;
private List list;
private Map map;
private Set set;
//学生所学多门课程
private List courseList;
public void setCourseList(List courseList) {
this.courseList = courseList;
}
public String[] getCourses() {
return courses;
}
public void setCourses(String[] courses) {
this.courses = courses;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public Set getSet() {
return set;
}
public void setSet(Set set) {
this.set = set;
}
}
体育
数学
张三
小三
SQL
Java
@Test
public void test01(){
AbstractApplicationContext abstractApplicationContext=new ClassPathXmlApplicationContext("bean2.xml");
stu stu=abstractApplicationContext.getBean("stu", bean_stu.stu.class);
String str= JSONObject.toJSONString(stu);
logger.info(str);
}
输出
集合里设置对象类型的值
util :命名空间,用以区分。
A
B
C
classpath:按照类的路径来搜索
spring 容器会依据路径来找对对应的properties文件,然后读取该文件的内容到properties
作用域 | 描述 |
---|---|
singleton | 在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,bean作用域范围的默认值。 |
prototype | 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()。 |
request | 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于web的Spring WebApplicationContext环境。 |
session | 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境。 |
application | 限定一个Bean的作用域为ServletContext的生命周期。该作用域仅适用于web的Spring WebApplicationContext环境。 |
生命周期:初始化,分配资源 销毁 释放资源。
自动装配指的是spring容器依据某种规则,自动建立对象之间的依赖关系
(默认情况下,容器不会自动装配。)可以通过指定autowire属性来告诉容器进行自动装配(容器实际上还是通过调用set方法或者构造器来完成依赖关系的建立。)
注解:注解是JDK5中推出的新特性,代码的特殊标记。
- 基于XML方式实现
- 基于注解方式实现
注解可以使用在类、方法、属性上面。
使用注解的目的,简化xml的配置方式。
配置组件扫描
base-package属性:指定要扫描的包名,spring容器会扫描该包及其子包下面的所有的类,如果该类前面有特定的注解。
(比如@Component),则spring容器会将其纳入容器进行管理(相当于这儿配置了一个bean元素)
通过注解来指定作用域
以上该四个注解底层都是基于@Component注解封装的,只是用于区分。
部分其他注解
@Autowired @Qualifier
@Component("res")
public class res {
/* @Autowired
@Qualifier("wt3")*/
private Waiter wt;
public Waiter getWt() {
return wt;
}
@Autowired
public void setWt(//注入进来的对象,类似于byName的属性。
@Qualifier("wt3") Waiter wt) {
this.wt = wt;
System.out.println("测试:服务员");
}
public res(){
System.out.println("res()");
}
}
@Resource
只支持set方式注入
可以将该注解添加属性前,使用name属性指定要注入的bean的ID,(不指定会按照byType方式进行注入)
可以将该注解添加到属性前。
@Component("bar")
public class Bar {
private Waiter wt;
public Waiter getWt() {
return wt;
}
@Resource(name = "wt3")
public void setWt(Waiter wt) {
this.wt = wt;
}
public Bar(){
System.out.println("11");
}
}
@Value注解
可以使用该注解来注入基本类型的值
也可以使用该注解来使用spring表达式
该注解可以添加到属性前,或者添加到对应的set方法前。
@Value("#{config.pagesize}")
private String pageSize;
@Configuration 注解
作为配置类,替代 xml 配置文件
@Configuration //作为配置类,替代 xml 配置文件
@ComponentScan(basePackages = { "bean"})
public class SpringConfig {
}
注解实例
@Component("b1")
@Scope("singleton")//单例和多例
@Lazy(true)//延迟加载
public class bean {
@Value("#{config.pagesize}")
private String pageSize;
@Value("alice")
private String name;
@PostConstruct
//初始化方法
public void init(){
System.out.println("初始化");
}
@PreDestroy
//销毁方法
public void destroy(){
System.out.println("销毁");
}
public bean(){
System.out.println("bean()");
}
@Bean(name="Bean")
public bean getBean(){
bean bean = new bean();
System.out.println("调用方法:"+bean);
return bean;
}
}
在本文中,我们揭开了 Spring 这个令软件行业为之动容的神秘面纱的一角。Spring 框架之所以如此备受推崇,不仅仅是因为它的灵活性和强大的功能,更因为它不断演进的能力,与软件发展的步伐同行。如果你对 Spring 框架的魅力产生了兴趣,那么请继续关注我们接下来的系列文章。在下一篇文章中,我们将深入探讨 Spring 的核心特性。
敬请期待!