Spring基础知识和入门案例

一、Spring是什么?

1.Spring是一个开源的优秀的轻量级的Java企业级应用框架

2.Spring是一个容器框架,其中管理了很多对象,这些对象都被称为Bean

3.Spring可以自动装配对象之间的依赖关系

4.开发者无需考虑对象之间如何依赖,在开发过程中可以实现组件之间的低耦合。

5.Spring本身是一个低侵入式的框架。

6.Spring遵循面向接口的编程,避免对象之间直接耦合。

二、Spring的两项基本技术。

传统的方式:控制器对象要用业务类对象,业务类对象要用Dao对象。控制器内要写代码拿到业务类对象(new 一个业务对象),业务类对象也要通过某种方式创建Dao对象。这种方式是对象之间的依赖关系要通过对象自身维护。

1.IoC:控制反转,又称为DI(依赖注入),即对象间的依赖关系由自身维护改变为有外部容器给定。

过滤器:可以把通用的功能写在一处。这就是面向切面的编程思想。

2.AOP:面向切面的编程,将系统中多个模块都要用到的通用功能,不在各模块中调用了,而是剥离出来单独开发维护,在运行时由外部容器应用于各个模块中,这样的一种技术即AOP.

三、ApplicationContext对象:即Spring容器对象接口。

1.通过@Configuration注解的类说明容器配置;

2.在@Configuration注解的类中通过@Bean注解的方法说明受容器管理的bean对象,默认对象的名字便是方法名,也可以通过@Bean的name或者value参数指定名称。

3.ApplicationContext对象默认受管对象为单例模式、非懒加载(即容器启动就创建加载对象),可以配置实现对象的原型模式(prototype)和懒加载。

4.容器可以配置初始化方法和销毁方法。

5.仅单例模式才有非懒加载。原型模式对象不受容器管理、一律懒加载、不能被容器销毁。

四、Spring的使用

1.Spring的官网:https://docs.spring.io/spring/docs/5.2.2.RELEASE/spring-framework-reference/core.html#spring-core

2.建一个maven项目,并在pom文件中引入jar包。(要用到的jar包:spring-context、log4j-core)

jar包在maven仓库中找:https://mvnrepository.com/

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>ztt.spring</groupId>
	<artifactId>spring_demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring_demo</name>


	<dependencies>
		<!-- 引入spring容器包 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.2.2.RELEASE</version>
		</dependency>
		<!-- 引入log4j日志包 -->
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.13.0</version>
		</dependency>

	</dependencies>

	<!-- 引入编译器插件 -->
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<!-- 编译级别 -->
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

 

3.配置log4j2.xml文件

log4j官网:https://logging.apache.org/log4j/2.x/ 拷贝配置信息

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
	<Appenders>
		<Console name="Console" target="SYSTEM_OUT">
			<PatternLayout
				pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
		</Console>
	</Appenders>
	<Loggers>
		<Logger name="ztt.spring.*" level="trace" additivity="false">
			<AppenderRef ref="Console" />
		</Logger>
		<Root level="debug">
			<AppenderRef ref="Console" />
		</Root>
	</Loggers>
</Configuration>

案例场景:饲养员给动物喂食。饲养员依赖动物和食物。传统的方式是要new一个动物和食物,饲养员要是改换动物和食物的话,就得改代码,可维护性降低了。所以饲养员和动物食物应该是低耦合的。在Java中要让一个对象抽象化,不那么具体,就要用到接口。

1.食物接口,得到食物名称

package ztt.spring;
//食物接口
public interface Food {
	//食物名称
 public String getName();
}

2.动物接口,动物可以吃食物

package ztt.spring;
//动物接口
public interface Animal {
	//动物吃食物
	public void eat(Food food);
}

3.饲养员类,给动物喂食物,需要动物和食物。在Spring中,对象之间的依赖关系通过属性来依赖。属性提供set方法。

package ztt.spring;
//饲养员类
public class Feeder {
	private Animal an;
	private Food fd;
	//工作
	public void work() {
		System.out.println("开始工作...");
		an.eat(fd);
		System.out.println("工作完成!");
	}
	public void setAn(Animal an) {
		this.an = an;
	}
	public void setFd(Food fd) {
		this.fd = fd;
	}
}

4.实现类-猫实现了动物接口,鱼实现了食物接口。

package ztt.spring.impl;
import ztt.spring.Animal;
import ztt.spring.Food;
public class Cat implements Animal {
	@Override
	public void eat(Food food) {
		System.out.println("猫吃:"+food.getName());
		
	}
}
package ztt.spring.impl;
import ztt.spring.Food;
public class Fish implements Food {
@Override
public String getName() {
	return "鱼";
}
}

以上对象还没有装配到一块,需要建立配置类。

5.配置类

package ztt.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import ztt.spring.impl.Cat;
import ztt.spring.impl.Fish;
import ztt.spring.impl.Mouse;

@Configuration//说明容器配置
public class AppConfig {	
	@Bean(name="myfeed")//受容器管理的一个bean,指定名字
	@Autowired//自动装配,默认按照类型装配,即自动在容器中寻找符合类型的对象给参数赋值
	public Feeder feeder( Animal an,Food fd) {
		Feeder feeder=new Feeder();
		feeder.setAn(an);
		feeder.setFd(fd);
		return feeder;
	}
	@Bean
	public Cat cat() {
		return new Cat();
	}
	@Bean 
	public Fish fish() {
		return new Fish();
	}

}

6.测试类

  6.1需要创建容器对象,参数为配置类。

  6.2从容器中获取对象,调取方法。

  6.3运行。

package spring_demo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import ztt.spring.AppConfig;
import ztt.spring.Feeder;

public class Test {

public static void main(String[] args) {
	//需要创建容器对象,参数为配置类。
	ApplicationContext ctx=
			new AnnotationConfigApplicationContext(AppConfig.class);
	//从容器中获取对象,调取方法。
	Feeder feeder=ctx.getBean(Feeder.class);
	feeder.work();
}

}

7.运行结果

新的问题:猫不吃鱼了,饲养员准备给他吃老鼠。

1.再来一个老鼠类,实现食物接口。

package ztt.spring.impl;

import ztt.spring.Food;
//老鼠类
public class Mouse implements Food {

@Override
public String getName() {
	return "老鼠";
}

}

2.在配置类中,配置一个bean。

package ztt.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import ztt.spring.impl.Cat;
import ztt.spring.impl.Fish;
import ztt.spring.impl.Mouse;

@Configuration//说明容器配置
public class AppConfig {	
	@Bean(name="myfeed")//受容器管理的一个bean,指定名字
	@Autowired//自动装配,默认按照类型装配,即自动在容器中寻找符合类型的对象给参数赋值
	public Feeder feeder( Animal an,Food fd) {
		Feeder feeder=new Feeder();
		feeder.setAn(an);
		feeder.setFd(fd);
		return feeder;
	}
	@Bean
	public Cat cat() {
		return new Cat();
	}
	@Bean 
	public Fish fish() {
		return new Fish();
	}

}

3.运行会报错

11:34:05.898 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@4ef782af
11:34:05.944 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
11:34:06.180 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
11:34:06.199 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
11:34:06.202 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
11:34:06.210 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'appConfig'
11:34:06.221 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'myfeed'
11:34:06.230 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'cat'
11:34:06.262 [main] WARN  org.springframework.context.annotation.AnnotationConfigApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myfeed' defined in ztt.spring.AppConfig: Unsatisfied dependency expressed through method 'feeder' parameter 1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'ztt.spring.Food' available: expected single matching bean but found 2: mouse,fish
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myfeed' defined in ztt.spring.AppConfig: Unsatisfied dependency expressed through method 'feeder' parameter 1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'ztt.spring.Food' available: expected single matching bean but found 2: mouse,fish
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:798)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:539)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
	at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:89)
	at spring_demo.Test.main(Test.java:14)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'ztt.spring.Food' available: expected single matching bean but found 2: mouse,fish
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:220)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1265)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:885)
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789)
	... 14 more

解决方法: 指定对象的优先装配@Primary加在方法名中或者在装配时在参数加注解@Qualifier("方法名")

package ztt.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import ztt.spring.impl.Cat;
import ztt.spring.impl.Fish;
import ztt.spring.impl.Mouse;

@Configuration//说明容器配置
public class AppConfig {	
	@Bean(name="myfeed")//受容器管理的一个bean,指定名字
	@Autowired//自动装配,默认按照类型装配,即自动在容器中寻找符合类型的对象给参数赋值
	
	public Feeder feeder(Animal an,@Qualifier("mouse") Food fd) {
		Feeder feeder=new Feeder();
		feeder.setAn(an);
		feeder.setFd(fd);
		return feeder;
	}
	@Primary//优先装配本对象
	@Bean
	public Mouse mouse() {
		return new Mouse();
	}
	@Bean
	public Cat cat() {
		return new Cat();
	}
	@Bean 
	public Fish fish() {
		return new Fish();
	}

}

运行结果

实际开发中spring的配置:

1.在appConfig类中加两个注解

@Configuration
@ComponentScan("ztt.spring")//组件扫描,参数为要扫描的子包,必须和@Configuration一起使用

2.在各个类(Feeder,Cat,Fish,Mouse)中加注解

@Component//说明受spring管理的对象,名称默认为首字母小写的类名,可以指定名称

3.在Feeder属性上加自动装配注解@Autowired

4.在Feeder类中的食物属性上面指定@Qualifier("mouse") 或在食物类上面加@Primary,以上注解是为了保持单例模式,优先使用哪个就在哪上上面指定优先级。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值