Spring v4

Spring v4.2框架–注解IoC&AOP

1.IoC注解开发

1.IoC注解开发入门

a)创建一个Web项目,引入jar包

在Spring4的版本中,除了要引入基本的开发包外,还需要引入一个aop包。

在这里插入图片描述

b)引入Spring的配置文件

在src目录下创建applicationContext.xml

使用注解开发,需要引入一个context约束。

<?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"> <!-- bean definitions here -->

</beans>
c)创建一个接口和实现类
d)开启Spring的组件扫描
<?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"> <!-- bean definitions here -->
	<!-- Springde IoC注解入门 -->
	<!-- 使用IoC的注解开发,配置扫描(哪些包下的类要使用注解) -->
	<context:component-scan base-package="com.nikehu.spring.demo1"/>
</beans>
e)在类上添加注解

UserDaoImpl.java

package com.nikehu.spring.demo1;

import org.springframework.stereotype.Component;

/**
 * 用户Dao实现类
 * @author 猪猪
 *
 */
@Component("userDao")//相当于<bean id="userDao" class="com.nikehu.spring.demo1.UserDaoImpl"/>
public class UserDaoImpl implements UserDao {

	public void save() {
		System.out.println("DAO中保存用户的方法执行了");
	}
}
f)编写测试类
	//spring的IoC注解方式
	@Test
	public void demo2(){
		ApplicationContext aContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDao bean = (UserDao) aContext.getBean("userDao");
		bean.save();
	}

2.IoC注解开发如何设置属性

使用注解方式可以没有set()方法,

  • 如果属性有set()方法,属性注入的注解就加在set()方法上,
  • 如果没有set()方法,属性注入的注解就加在属性上。
package com.nikehu.spring.demo1;

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

/**
 * 用户Dao实现类
 * @author 猪猪
 *
 */
@Component("userDao")//相当于<bean id="userDao" class="com.nikehu.spring.demo1.UserDaoImpl"/>
public class UserDaoImpl implements UserDao {
	private String name;
	
	@Value("zhangsan")
	public void setName(String name) {
		this.name = name;
	}

	public void save() {
		System.out.println("DAO中保存用户"+name+"的方法执行了");
	}
}
package com.nikehu.spring.demo1;

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

/**
 * 用户Dao实现类
 * @author 猪猪
 *
 */
@Component("userDao")//相当于<bean id="userDao" class="com.nikehu.spring.demo1.UserDaoImpl"/>
public class UserDaoImpl implements UserDao {
	@Value("zhangsan")
	private String name;

	public void save() {
		System.out.println("DAO中保存用户"+name+"的方法执行了");
	}
}

3.IoC的注解的详解

1.@Component:组件
  • 用于修饰一个类,将这个类交给Spring管理(前提:当前类所在的包已经添加了包扫描)
  • 这个注解有三个衍生注解(功能类似):
    • @Controller​:? Web层
    • @Service:Service层
    • @Repository:dao层
2.属性注入的注解
  • 普通属性:
    • @Value:设置普通属性的注解
  • 对象类型属性:
    • @Autowired:设置对象类型属性的注解,但是它是按照类型完成属性的注入。
      • 我们的习惯是按照名称来完成属性的注入:必须让@Autowired注解和@Qualifier()一起使用完成按照名称属性注入。
    • @Resource():完成对象类型的属性注入,按照名称完成属性注入(需要加入javax的扩展包)
	@Test
	public void demo3(){
		ApplicationContext aContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserService service = (UserService) aContext.getBean("userService");
		service.save();
	}
package com.nikehu.spring.demo1;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service("userService")
public class UserServiceImpl implements UserService {
	//注入dao
	@Autowired
	@Qualifier("userDao")
	private UserDao dao;
	
	public void save() {
		System.out.println("UserService的save()方法执行了。。");
		dao.save();		
	}	
}
package com.nikehu.spring.demo1;

public interface UserService {
	void save();
}
package com.nikehu.spring.demo1;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service("userService")
public class UserServiceImpl implements UserService {
	//注入dao
	@Resource(name="userDao")
	private UserDao dao;
	
	public void save() {
		System.out.println("UserService的save()方法执行了。。");
		dao.save();		
	}	
}

4.Bean的其他注解

生命周期注解
  • @PostConstruct //相当于xml中的init-method
  • @PreDestroy //相当于xml中的destory-method,必须关闭工厂才会销毁实例
package com.nikehu.spring.demo2;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.stereotype.Service;

@Service("customerService")
@Scope
public class CustomerService {
	
	@PostConstruct	//相当于xml中的init-method
	public void init(){
		System.out.println("Service的init方法执行了");
	}
	
	public void save(){
		System.out.println("Service的save方法执行了");
	}

	@PreDestroy	//相当于xml中的destory-method
	public void destory(){
		System.out.println("Service的destory方法执行了");
	}
}
Bean的作用范围的注解
  • @Scope:作用范围,取值有:
    • singleton:单例,默认
    • prototype:多例
    • request
    • session
    • globalsession

5.Spring的IoC的XML和注解整合开发

二者比较:
  • 适用场景:
  • xml适用任何场景
    • 结构清晰,后期维护方便
  • 注解:有些地方用不了,这个类不是自己提供
    • 纯注解(SSH),开发方便

xml和注解整合开发

xml用于配置Bean,可以看到我们将哪些类交给了Spring管理。

注解用于属性注入,使得类很干净,set方法也可以没有。

package com.nikehu.spring.demo3;

import javax.annotation.Resource;


public class ProductService {
	@Resource(name="productDao")
	private ProductDao productDao;
	@Resource(name="orderDao")
	private OrderDao orderDao;
	 
	public void save(){
		System.out.println("productService的save方法执行了。。。");
		productDao.save();
		orderDao.save();
	}
}
package com.nikehu.spring.demo3;

public class ProductDao {
	
	public void save(){
		System.out.println("productDao的save方法执行了。。。");
	}
}
package com.nikehu.spring.demo3;

public class OrderDao {
	
	public void save(){
		System.out.println("orderDao的save方法执行了。。。");
	}
}
<?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"> <!-- bean definitions here -->
	<!-- Spring 的 IoC注解入门 -->
	<!-- 使用IoC的注解开发,配置扫描(哪些包下的类要使用注解),扫描是为了扫描类上的注解 -->
	<!-- <context:component-scan base-package="com.nikehu.spring"/> -->
	<!-- <context:component-scan base-package="com.nikehu.spring.demo2"/> -->
    <!-- 在没有包扫描的情况下,使用属性注入:@Resource,@Value,@Autowired,@Qulifier -->
	<context:annotation-config />
	<bean id="productDao" class="com.nikehu.spring.demo3.ProductDao"/>
	<bean id="orderDao" class="com.nikehu.spring.demo3.OrderDao"/>
	<bean id="productService" class="com.nikehu.spring.demo3.ProductService"/>
</beans>

2.AOP的XML开发(AspectJ的XML的方式)

1.AOP概述

AOP(Aspect Oriented Programming,面向切面编程)

​ 面向切面编程,通过预编译方式和运行时期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发的一个热点,也是spring框架中的一个重要内容,是函数式编程的一种衍生泛型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑个部分之间的耦合度降低,提高程序的可复用性,同时提高了开发效率。

AOP的应用场景

在这里插入图片描述

对程序进行增强:在不修改源码的情况下

AOP可以进行权限校验,日志记录,性能监控,事务控制

Spring的AOP的由来

AOP最早由AOP联盟组织提出的,制定了一套规范,Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范。

底层实现:
  • 动态代理:底层使用了两种动态代理
    • JDK动态代理:缺陷,只能对实现了接口的类产生动态代理
    • Cglib动态代理(类似于Javassist第三方的代理技术):对没有实现接口的对象产生动态代理。生成子类对象

2.JDK动态代理

package com.nike.spring.demo01;

public interface UserDao {
	void save();
	void update();
	void delete();
	void find();
}
package com.nike.spring.demo01;

public class UserDaoImpl implements UserDao {

	public void save() {
		System.out.println("这是保存用户");
	}

	public void update() {
		System.out.println("这是修改用户");
	}

	public void delete() {
		System.out.println("这是删除用户");
	}

	public void find() {
		System.out.println("这是查找用户");
	}
}
package com.nike.spring.demo01;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 使用JDK的动态代理对UserDao产生代理
 * @author 猪猪
 *
 */
public class JdkProxy implements InvocationHandler{
	//将被增强的对象传递到代理当中
	private UserDao dao;
	
	public JdkProxy(UserDao dao){
		this.dao = dao;
	}
	/**
	 * 产生UserDao的动态代理
	 * @return
	 */
	public UserDao createProxy(){
		UserDao userDao = (UserDao) Proxy.newProxyInstance(
				dao.getClass().getClassLoader(), 
				dao.getClass().getInterfaces(), 
				this);
		return userDao;
	}
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		//判断方法名
		if("save".equals(method.getName())){
			//增强
			System.out.println("权限检验");
			return method.invoke(dao, args);
		}
		return method.invoke(dao, args);
	}
}
package com.nike.spring.demo01;

import org.junit.Test;

public class SpringDemo01 {
	
	@Test
	public void demo01(){
		UserDao userDao = new UserDaoImpl();
		userDao.find();
		userDao.save();
		userDao.update();
		userDao.delete();
	}
	//动态代理
	@Test
	public void demo02(){
		UserDao userDao = new UserDaoImpl();
		//创建代理
		userDao = (UserDao) new JdkProxy(userDao).createProxy();
		userDao.find();
		userDao.save();
		userDao.update();
		userDao.delete();
	}
}

3.Cglib动态代理

  • Cglib(Code Generation Library):是一个强大的,高性能的,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。第三方开源代码生成库,动态添加类的属性和行为。
package com.nike.spring.demo02;

public class CustomerDao {
	public void save(){
		System.out.println("CustomerDao的save方法执行了。。。。");
	}
	public void find(){
		System.out.println("CustomerDao的find方法执行了。。。。");
	}
	public void update(){
		System.out.println("CustomerDao的update方法执行了。。。。");
	}
	public void delete(){
		System.out.println("CustomerDao的delete方法执行了。。。。");
	}
}
package com.nike.spring.demo02;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

/**
 * Cglib动态代理
 * @author 猪猪
 *
 */
public class CglibProxy implements MethodInterceptor{
	
	private CustomerDao dao;
	public CglibProxy(CustomerDao dao) {
		this.dao = dao;
	}
	/**
	 * 使用Cglib产生代理的方法
	 */
	public CustomerDao createProxy(){
		//1.创建Cglib的核心对象
		Enhancer enhancer = new Enhancer();
		//2.设置父类
		enhancer.setSuperclass(dao.getClass());
		//3.设置回调(类似于InvocationHandler对象)
		enhancer.setCallback(this);
		//4.创建代理对象
		CustomerDao create = (CustomerDao) enhancer.create();
		
		return create;
	}
	public Object intercept(Object proxy, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		//判断方法名
		if("save".equals(method.getName())){
			System.out.println("权限校验。。。。。。");
			return methodProxy.invokeSuper(proxy, args);
		}
		return methodProxy.invokeSuper(proxy, args);
	}
}
package com.nike.spring.demo02;

import org.junit.Test;

public class SpringDemo02 {
	@Test
	/**
	 * Cglib动态代理测试
	 */
	public void demo01(){
		CustomerDao dao = new CustomerDao();
		dao.save();
		dao.delete();
		dao.find();
		dao.update();
	}
	@Test
	/**
	 * Cglib动态代理测试
	 */
	public void demo02(){
		CustomerDao dao = new CustomerDao();
		CustomerDao proxy = new CglibProxy(dao).createProxy();
		
		proxy.save();
		proxy.delete();
		proxy.find();
		proxy.update();
	}
}

4.Spring的AOP简介

AOP思想

Spring的AOP有自己的实现方式(非常繁琐)。

AspectJ是一个AOP框架,Spring引入AspectJ作为自身的AOP开发。

Spring有两套AOP开发方式

  • Spring传统方式(弃用)
  • Spring基于AspectJ的AOP开发(使用)

5.AOP的相关术语

JoinPoint(连接点):被拦截到的点(方法),Spring只支持方法类型的连接点

Pointcut(切入点):指我们要对哪些Joinpoint进行拦定义。

Advice(通知/增强):通知是指拦截到Joinpoint之后要做的事情就是通知,通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(方法层面的增强)

Introduction(引介):一种特殊的通知在不修改类代码的前提下,Introduction可以在运行期为类动态的添加一些方法或属性。(类层面的增强)

Target(目标):代理的目标对象

Weaving(织入):指把增强应用到目标对象来创建新的代理对象的过程。

Spring采用的是动态代理织入,而AspectJ采用编译期织入类装载期织入

proxy(代理)一个类被AOP织入增强后,就产生一个结果代理类

Aspect(切面):是切入点和通知的结合。

在这里插入图片描述

6.AOP开发入门(AspectJ的xml方式)

1)创建Web项目,引入jar包

  • 引入基本开发包

  • 引入aop开发的相关jar包

    • 4个 在这里插入图片描述

    • 引入aop的约束

    • <?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
              http://www.springframework.org/schema/beans 
              http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/aop 
              http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->
      
      </beans>
      

2)编写目标类

package com.nike.spring.demo03;

public interface ProductDao {
	public void save();
	public void update();
	public void find();
	public void delete();
}
package com.nike.spring.demo03;

public class ProductDaoImpl implements ProductDao {

	public void save() {
		System.out.println("保存商品");

	}

	public void update() {
		System.out.println("修改商品");

	}

	public void find() {
		System.out.println("查找商品");
	}

	public void delete() {
		System.out.println("删除商品");
	}
}
	<!-- 配置目标对象  -->
	<bean id="productDao" class="com.nike.spring.demo03.ProductDaoImpl"></bean>

3)编写测试类

  • spring整合Junit

    • 引入jar包:spring-test-4.2.4.RELEASE.jar

    • package com.nike.spring.demo03;
      
      import javax.annotation.Resource;
      
      import org.junit.Test;
      import org.junit.runner.RunWith;
      import org.springframework.test.context.ContextConfiguration;
      import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
      
      //固定写法
      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration("classpath:applicationContext.xml")
      public class SpringDemo3 {
      	@Resource(name="productDao")
      	private ProductDao dao;
      	
      	@Test
      	public void demo01(){
      		dao.save();
      		dao.delete();
      		dao.find();
      		dao.update();
      	}
      }
      

4)增强save()方法,编写一个切面类。

package com.nike.spring.demo03;
/**
 * 切面类
 * @author 猪猪
 *
 */
public class MyAspectXML {
	
	public void checkPri(){
		System.out.println("权限校验。。。。。。。");
	}
}

5)配置切面类,将切面类交给spring

<bean id="myAspect" class="com.nike.spring.demo03.MyAspectXML"></bean>

6)通过AOP的配置实现,然后直接运行测试类

	<!-- 配置目标对象  -->
	<bean id="productDao" class="com.nike.spring.demo03.ProductDaoImpl"></bean>
	<bean id="myAspect" class="com.nike.spring.demo03.MyAspectXML"></bean>
	<!-- 通过AOP的配置完成对目标类产生代理 -->
	<aop:config>
		<!-- expression表达式用于配置那些类的那些方法需要进行增强 
			*com.nike.spring.demo03.ProductDaoImpl.save(..)
			*:代指任意返回值
			..:代指任意参数
		-->
		<aop:pointcut expression="execution(* com.nike.spring.demo03.ProductDaoImpl.save(..))" id="pointcut1"/>
		<!-- 配置切面
			ref:切面类的id
		 -->
		<aop:aspect ref="myAspect">
			<aop:before method="checkPri" pointcut-ref="pointcut1"/>
		</aop:aspect>
	</aop:config>

7.通知的类型

前置通知:在目标方法执行之前进行操作;可以获得切入点的信息

<aop:before method="checkPri" pointcut-ref="pointcut1"/>
	public void checkPri(JoinPoint point){
		System.out.println(point);
		System.out.println("权限校验。。。。。。。");
	}

后置通知:在目标方法执行之后进行操作;可以获得切入点的信息,可以获取方法返回值

			<!-- 后置通知 -->
			<aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result"/>
	/**
	 * 后置通知
	 */
	public void writeLog(Object result){
		System.out.println("日志记录。。。。。。。"+result);
	}

环绕通知:在目标方法执行之前和之后进行操作;可以阻止目标方法的执行

	/**
	 * 环绕通知
	 * 监控性能
	 * @param point
	 * @return
	 * @throws Throwable 
	 */
	public Object around(ProceedingJoinPoint point) throws Throwable{
		System.out.println("环绕前。。。。。。。");
		Object obj = point.proceed();
		System.out.println("环绕后。。。。。。。");
		return obj;
	}
			<!-- 环绕通知 -->
			<aop:around method="around" pointcut-ref="pointcut3"/>

异常抛出通知:在程序出现异常的时候进行操作;

最终通知:无论代码是否出现异常,最终通知总会执行;

引介通知

<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->
	<!-- 配置目标对象  -->
	<bean id="productDao" class="com.nike.spring.demo03.ProductDaoImpl"></bean>
	<bean id="myAspect" class="com.nike.spring.demo03.MyAspectXML"></bean>
	<!-- 通过AOP的配置完成对目标类产生代理 -->
	<aop:config>
		<!-- expression表达式用于配置那些类的那些方法需要进行增强 
			*com.nike.spring.demo03.ProductDaoImpl.save(..)
			*:代指任意返回值
			..:代指任意参数
		-->
		<aop:pointcut expression="execution(* com.nike.spring.demo03.ProductDaoImpl.save(..))" id="pointcut1"/>
		<aop:pointcut expression="execution(* com.nike.spring.demo03.ProductDaoImpl.delete(..))" id="pointcut2"/>
		<aop:pointcut expression="execution(* com.nike.spring.demo03.ProductDaoImpl.update(..))" id="pointcut3"/>
		<aop:pointcut expression="execution(* com.nike.spring.demo03.ProductDaoImpl.find(..))" id="pointcut4"/>
		<!-- 配置切面
			ref:切面类的id
		 -->
		<aop:aspect ref="myAspect">
			<!-- 前置通知 -->
			<aop:before method="checkPri" pointcut-ref="pointcut1"/>
			<!-- 后置通知 -->
			<aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result"/>
			<!-- 环绕通知 -->
			<aop:around method="around" pointcut-ref="pointcut3"/>
			<!-- 异常抛出通知 -->
			<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>	
			<!-- 最终通知 -->		
			<aop:after-throwing method="after" pointcut-ref="pointcut4"/>			
		</aop:aspect>
	</aop:config>
</beans>
package com.nike.spring.demo03;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 切面类
 * @author 猪猪
 *
 */
public class MyAspectXML {
	/**
	 * 前置通知
	 * @param point
	 */
	public void checkPri(JoinPoint point){
		System.out.println(point);
		System.out.println("权限校验。。。。。。。");
	}
	
	/**
	 * 后置通知
	 */
	public void writeLog(Object result){
		System.out.println("日志记录。。。。。。。"+result);
	}
	/**
	 * 环绕通知
	 * 监控性能
	 * @param point
	 * @return
	 * @throws Throwable 
	 */
	public Object around(ProceedingJoinPoint point) throws Throwable{
		System.out.println("环绕前。。。。。。。");
		Object obj = point.proceed();
		System.out.println("环绕后。。。。。。。");
		return obj;
	}
	/**
	 * 异常抛出通知
	 */
	public void afterThrowing(Throwable ex){
		System.out.println("异常抛出通知。。。。。。。。"+ex.getMessage());
		
	}
	
	/**
	 * 最终通知:相对于finally代码块
	 * 
	 */
	public void after(){
		System.out.println("最终通知。。。。。。。。");
	}
}
package com.nike.spring.demo03;

public class ProductDaoImpl implements ProductDao {

	public void save() {
		System.out.println("保存商品");

	}

	public void update() {
		System.out.println("修改商品");

	}

	public void find() {
		System.out.println("查找商品");
		int i = 1/0;
	}

	public String delete() {
		System.out.println("删除商品");
		return "返回值";
	}
}

8.切入点表达式写法

expression="execution(* com.nike.spring.demo03.ProductDaoImpl.find(..))"

语法格式:基于execution的函数完成

[访问修饰符] 方法返回值 包名.类名.方法名(参数)

在这里插入图片描述

Spring Cloud是一个分布式微服务架构下的一站式解决方案,它是各个微服务架构落地技术的集合体,被称为微服务全家桶。\[2\]Spring Cloud集成了Ribbon和Eureka,可以在使用Feign时提供负载均衡的HTTP客户端。\[1\] 与此相比,Spring Boot专注于快速方便地开发单个个体微服务。它可以独立使用开发项目,而Spring Cloud则是关注全局的微服务协调治理框架,将使用Spring Boot开发的单体微服务整合并管理起来,为各个微服务之间提供配置发现、服务发现、路由、微代理、时间总线、全局锁、决策竞选、分布式会话等集成服务。可以说,Spring Boot可以离开Spring Cloud单独使用开发项目,但是Spring Cloud离不开Spring Boot,它们之间存在依赖关系。\[2\] 相比之下,Dubbo和Spring Cloud有一些区别。Spring Cloud利用Spring Boot的开发便利性,简化了分布式系统基础设施的开发,为开发人员提供了快速构建分布式系统的工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。而Dubbo则是阿里巴巴开源的一款高性能Java RPC框架,主要用于提供分布式服务治理的解决方案。\[3\] #### 引用[.reference_title] - *1* *2* *3* [SpringCloud详解](https://blog.csdn.net/m0_56116754/article/details/126387535)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v4^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值