Spring IOC和AOP 原理彻底搞懂

article/2025/9/18 10:20:37

本博中关于Spring的文章:Spring IOC和AOP原理,Spring事务原理探究,Spring配置文件属性详解,Spring中的代理模式


Spring提供了很多轻量级应用开发实践的工具集合,这些工具集以接口、抽象类、或工具类的形式存在于Spring中。通过使用这些工具集,可以实现应用程序与各种开源技术及框架间的友好整合。比如有关jdbc封装的数据访问工具Spring JDBC,有关编写单元测试的spring test包以及spring-mock,有关访问动态脚本语言的Spring Script,另外还有发送邮件的工具Spring Mail、日程及任务处理工具Spring scheduling等。 可以这么说,大多数企业级应用开发中经常涉及到的一些通用的问题,都可以通过Spring提供的一些实用工具包轻松解决

依赖注入的三种方式:(1)接口注入(2)Construct注入(3)Setter注入

控制反转(IoC)与依赖注入(DI)是同一个概念,引入IOC的目的:(1)脱开、降低类之间的耦合;(2)倡导面向接口编程、实施依赖倒换原则; (3)提高系统可插入、可测试、可修改等特性。
具体做法:(1)将bean之间的依赖关系尽可能地抓换为关联关系;
(2)将对具体类的关联尽可能地转换为对Java interface的关联,而不是与具体的服务对象相关联;
(3)Bean实例具体关联相关Java interface的哪个实现类的实例,在配置信息的元数据中描述;
(4)由IoC组件(或称容器)根据配置信息,实例化具体bean类、将bean之间的依赖关系注入进来。

org.springframework.beans及org.springframework.context包是Spring IoC容器的基础。BeanFactory提供的高级配置机制,使得管理任何性质的对象成为可能。ApplicationContext是BeanFactory的扩展,功能得到了进一步增强,比如更易与Spring AOP集成、消息资源处理(国际化处理)、事件传递及各种不同应用层的context实现(如针对web应用的WebApplicationContext)。 简而言之,BeanFactory提供了配制框架及基本功能,而ApplicationContext则增加了更多支持企业核心内容的功能。ApplicationContext完全由BeanFactory扩展而来,因而BeanFactory所具备的能力和行为也适用于ApplicationContext。

IoC容器负责容纳bean,并对bean进行管理。在Spring中,BeanFactory是IoC容器的核心接口。它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。Spring为我们提供了许多易用的BeanFactory实现,XmlBeanFactory就是最常用的一个。该实现将以XML方式描述组成应用的对象以及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。

实现化容器:

Resource resource = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
... 或...
ClassPathResource resource = new ClassPathResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
... 或...
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
// of course, an ApplicationContext is just a BeanFactory
BeanFactory factory = (BeanFactory) context;
将XML配置文件分拆成多个部分是非常有用的。为了加载多个XML文件生成一个ApplicationContext实例,可以将文件路径作为字符串数组传给ApplicationContext构造器。而bean factory将通过调用bean defintion reader从多个文件中读取bean定义。
通常情况下,Spring团队倾向于上述做法,因为这样各个配置并不会查觉到它们与其他配置文件的组合。另外一种方法是使用一个或多个的 <import/>元素来从另外一个或多个文件加载bean定义。所有的 <import/>元素必须放在 <bean/>元素之前以完成bean定义的导入。 让我们看个例子:
<beans><import resource="services.xml"/><import resource="resources/messageSource.xml"/><import resource="/resources/themeSource.xml"/><bean id="bean1" class="..."/><bean id="bean2" class="..."/></beans>
在上面的例子中,我们从3个外部文件: services.xmlmessageSource.xmlthemeSource.xml来加载bean定义。这里采用的都是相对路径,因此,此例中的 services.xml一定要与导入文件放在同一目录或类路径,而 messageSource.xmlthemeSource.xml的文件位置必须放在导入文件所在目录下的 resources目录中。正如你所看到的那样,开头的斜杠‘/’实际上可忽略。因此不用斜杠‘/’可能会更好一点。
根据Spring XML配置文件的Schema(或DTD),被导入文件必须是完全有效的XML bean定义文件,且根节点必须为 <beans/> 元素。

BeanFactory和FactoryBean的区别,简而言之,BeanFactory是加载的容器,加载一切的BEAN,而FactoryBean用于创建代理类
===============================================================上面已讲到
 BeanFactory它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖
FactoryBean(通常情况下,bean无须自己实现工厂模式,Spring容器担任工厂角色;但少数情况下,容器中的bean本身就是工厂,其作用是产生其它bean实例),作用是产生其他bean实例。通常情况下,这种bean没有什么特别的要求,仅需要提供一个工厂方法,该方法用来返回其他bean实例。由工厂bean产生的其他bean实例,不再由Spring容器产生,因此与普通bean的配置不同,不再需要提供class元素。

ProxyFactoryBean用于创建代理(根据Advisor生成的Bean,也就是TargetBean的代理)
我们的Advisor,PointCut等等,其最终目的都是为了创建这个代理。
===============================================================下面将讲到

AOP全名Aspect-Oriented Programming,中文直译为面向切面(方面)编程,当前已经成为一种比较成熟的编程思想,可以用来很好的解决应用系统中分布于各个模块的交叉关注点问题。在轻量级的J2EE中应用开发中,使用AOP来灵活处理一些具有横切性质的系统级服务,如事务处理、安全检查、缓存、对象池管理等,已经成为一种非常适用的解决方案。 AOP中比较重要的概念有:Aspect、JoinPoint、PonitCut、Advice、Introduction、Weave、Target Object、Proxy Object等

引介(Introduction)是指给一个现有类添加方法或字段属性,引介还可以在不改变现有类代码的情况下,让现有的Java类实现新的接口,或者为其指定一个父类从而实现多重继承。相对于增强(Advice)可以动态改变程序的功能或流程来说,引介(Introduction)则用来改变一个类的静态结构。比如我们可以让一个现有为实现java.lang.Cloneable接口,从而可以通过clone()方法复制这个类的实例。

拦截器是用来实现对连接点进行拦截,从而在连接点前或后加入自定义的切面模块功能。在大多数JAVA的AOP框架实现中,都是使用拦截器来实现字段访问及方法调用的拦截(interception)。所用作用于同一个连接点的多个拦截器组成一个连接器链(interceptor chain),链接上的每个拦截器通常会调用下一个拦截器。Spring AOP及JBoos AOP实现都是采用拦截器来实现的。

面向对象编程(OOP)解决问题的重点在于对具体领域模型的抽象,而面向切面编程(AOP)解决问题的关键则在于对关注点的抽象。也就是说,系统中对于一些需要分散在多个不相关的模块中解决的共同问题,则交由AOP来解决;AOP能够使用一种更好的方式来解决OOP不能很好解决的横切关注点问题以及相关的设计难题来实现松散耦合。因此,面向方面编程 (AOP) 提供另外一种关于程序结构的思维完善了OOP,是OOP的一种扩展技术,弥补补了OOP的不足。


AOP概念详解:注意以下实例<aop:开头的AspectJ的概念,Spring没有分的这么细。

  — 方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是一个很好的横切关注点例子。方面用Spring的Advisor或拦截器实现, 然后可以通过@Aspect标注或在applictionContext.xml中进行配置: 

      <aop:aspect id="fourAdviceAspect" ref="fourAdviceBean" order="2"

  — 连接点(Joinpoint):程序执行过程中的行为,如方法的调用或特定的异常被抛出,在代码上有JoinPoint类和ProceedingJoinPoint类,如下所示,可以通过JoinPoint获取很多参数,JoinPoint一般用在Advice实现方法中作为参数传入,ProceedingJoinPoint用于实现围绕Advice的参数传入。  通过下面JoinPoint的接口可以看出通过JoinPoint可以得到代理对象和Target对象。

package org.aspectj.lang;
import org.aspectj.lang.reflect.SourceLocation;
public interface JoinPoint {String toString();         //连接点所在位置的相关信息String toShortString();     //连接点所在位置的简短相关信息String toLongString();     //连接点所在位置的全部相关信息Object getThis();         //返回AOP代理对象Object getTarget();       //返回目标对象Object[] getArgs();       //返回被通知方法参数列表Signature getSignature();  //返回当前连接点签名SourceLocation getSourceLocation();//返回连接点方法所在类文件中的位置String getKind();        //连接点类型StaticPart getStaticPart(); //返回连接点静态部分
}public interface ProceedingJoinPoint extends JoinPoint {public Object proceed() throws Throwable;public Object proceed(Object[] args) throws Throwable;
}

      — 切入点(Pointcut):指定一个Adivce将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点,例如,使用正则表达式。

          xml中配置:

<aop:pointcut id="myPointcut" expression="execution(* com.wicresoft.app.service.impl.*.*(..))" method="release" /> 

          或使用Annoation :@pointcut("execution * transfer(..)")并用一个返回值为void,方法体为空的方法来命名切入点如:  private void anyOldTransfer(){}

     之后就可以在Advice中引用,如: @AfterReturning(pointcut="anyOldTransfer()", returning="reVal")  

package org.springframework.aop;
public interface Pointcut {ClassFilter getClassFilter();MethodMatcher getMethodMatcher();Pointcut TRUE = TruePointcut.INSTANCE;
}
package org.springframework.aop;
public interface ClassFilter {boolean matches(Class<?> clazz);//如果clazz与我们关注的现象相符时返回true,负责返回falseClassFilter TRUE = TrueClassFilter.INSTANCE;//静态参数 如果类型对于要扑捉的Pointcut来说无所谓,可将此参数传递给Pointcut
}
package org.springframework.aop;
public interface MethodMatcher {boolean matches(Method method, Class<?> targetClass);/*** 是否对参数值敏感* 如果为false表明匹配时不需要判断参数值(参数值不敏感),称之为StaticMethodMatcher,这时只有* matches(Method method, Class<?> targetClass); 被执行,执行结果可以缓存已提高效率。* 如果为true表明匹配时需要判断参数值(参数值敏感),称之为DynamicMethodMatcher,这时先执行* matches(Method method, Class<?> targetClass);如果返回true,然后再执行* boolean matches(Method method, Class<?> targetClass, Object[] args);已做进一步判断* */boolean isRuntime();boolean matches(Method method, Class<?> targetClass, Object[] args);MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
}

关于PointCut中使用的execution的说明:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?) 

modifiers-pattern:方法的操作权限

ret-type-pattern:返回值

declaring-type-pattern:方法所在的包

name-pattern:方法名

parm-pattern:参数名

throws-pattern:异常

记忆法则就是Java定义一个方法时的样子:public boolean produceValue(int oo) throws Exception, 只要在方法名前加上包名就可以了。

其中,除ret-type-pattern和name-pattern之外,其他都是可选的。上例中,execution(* com.spring.service.*.*(..))表示com.spring.service包下,返回值为任意类型;方法名任意;参数不作限制的所有方法。

常见的PointCut结构图:


  — 通知(Advice):在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。Advice中必须用到PointCut

     在xml中配置,配置中的method为Aspect实现类中的方法名,使用pointcut自定义或pointcut-ref进行引用已有pointcut

       <aop:before pointcut="execution(* com.wicresoft.app.service.impl.*.*(..))" method="authority" /> 

       <aop:after pointcut="execution(* com.wicresoft.app.service.impl.*.*(..))" method="release" /> 

       <aop:after-returning pointcut="execution(* com.wicresoft.app.service.impl.*.*(..))" method="log" />

       <aop:around pointcut="execution(* com.wicresoft.app.service.impl.*.*(..))" method="processTx" /> 

       <aop:after-throwing pointcut-ref="myPointcut" method="doRecovertyActions" throwing="ex" />     

     或使用Annoation: 

       @Before("execution(* com.wicresoft.app.service.impl.*.*(..))")

       @AfterReturning(returning="rvt", pointcut="execution(* com.wicresoft.app.service.impl.*.*(..))")

       @AfterThrowing(throwing="ex", pointcut="execution(* com.wicresoft.app.service.impl.*.*(..))")

       @After("execution(* com.wicresoft.app.service.impl.*.*(..))")

       @Around("execution(* com.wicresoft.app.service.impl.*.*(..))")  

注意

  • AfterReturning 增强处理处理只有在目标方法成功完成后才会被织入。
  • After 增强处理不管目标方法如何结束(保存成功完成和遇到异常中止两种情况),它都会被织入。

使用方法拦截器的around通知,需实现接口MethodInterceptor:

public interface MethodInterceptor extends Interceptor {

    Object invoke(MethodInvocation invocation) throws Throwable;

}

invoke()方法的MethodInvocation 参数暴露将被调用的方法、目标连接点、AOP代理和传递给被调用方法的参数。 invoke()方法应该返回调用的结果:连接点的返回值。

一个简单的MethodInterceptor实现看起来如下:

public class DebugInterceptor implements MethodInterceptor {public Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("Before: invocation=[" + invocation + "]");Object rval = invocation.proceed();System.out.println("Invocation returned");return rval;}
}

注意MethodInvocation的proceed()方法的调用。这个调用会应用到目标连接点的拦截器链中的每一个拦截器。大部分拦截器会调用这个方法,并返回它的返回值。但是, 一个MethodInterceptor,和任何around通知一样,可以返回不同的值或者抛出一个异常,而不调用proceed方法。但是,没有好的原因你要这么做。

Before通知:需实现MethodBeforeAdvice接口

public interface MethodBeforeAdvice extends BeforeAdvice {

    void before(Method m, Object[] args, Object target) throws Throwable;

}

Throw通知,需实现ThrowsAdvice接口

After Returning通知须直线AfterReturningAdvice接口

public interface AfterReturningAdvice extends Advice {

    void afterReturning(Object returnValue, Method m, Object[] args, Object target)

            throws Throwable;

}

       — 引入(Introduction):添加方法或字段到被通知的类,引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现IsModified接口,来简化缓存。使用introduction要有三个步骤(1)声明新接口(2)创建自己的IntrouductionInterceptor通过Implements IntroductionInterceptor或extends DelegatingIntroductionInterceptor 并同时implements(1)中声明的接口 (3)将新接口和自定义的IntroductionInterceptor配置到DefaultIntroductionAdvisor中,然后将前三者配置到ProxyFactoryBean中。

public interface IOtherBean {public void doOther();
}public class SomeBeanIntroductionInterceptor implements IOtherBean, IntroductionInterceptor {public void doOther() {System.out.println("doOther!");}public Object invoke(MethodInvocation invocation) throws Throwable {//判断调用的方法是否为指定类中的方法if ( implementsInterface(invocation.getMethod().getDeclaringClass()) ) {return invocation.getMethod().invoke(this, invocation.getArguments());}return invocation.proceed();}/*** 判断clazz是否为给定接口IOtherBean的实现*/public boolean implementsInterface(Class clazz) {return clazz.isAssignableFrom(IOtherBean.class);}
}

	<!-- 目标对象 --><bean id="someBeanTarget" class="aop.spring.introduction.SomeBeanImpl" /><!-- 通知 --><bean id="someBeanAdvice" class="aop.spring.introduction.SomeBeanIntroductionInterceptor" /><!-- 通知者,只能以构造器方法注入--><bean id="introductionAdvisor" class="org.springframework.aop.support.DefaultIntroductionAdvisor"><constructor-arg ref="someBeanAdvice" /><constructor-arg value="aop.spring.introduction.IOtherBean" />	</bean><!-- 代理 (将我们的切面织入到目标对象)--><bean id="someBeanProxy" class="org.springframework.aop.framework.ProxyFactoryBean"><!-- 若目标对象实现了代理接口,则可以提供代理接口的配置 --><property name="proxyInterfaces"  value="aop.spring.introduction.ISomeBean" /><!-- 配置目标对象 --><property name="target" ref="someBeanTarget" /><!-- 配置切面 --><property name="interceptorNames"><list><value>introductionAdvisor</value></list></property></bean>


    — 拦截器(Advisor )常用的有PointCutAdvisor和IntroudtionAdvisor。前者Advisor有PointCut和Advice组成,满足Poincut(指定了哪些方法需要增强),则执行相应的Advice(定义了增强的功能),后者由Introduction构成。PointCutAdvisor主要是根据PointCut中制定的Target Objects的方法在调用(前,后,around,throws, after-return等)时引入新的Aspect中的methods, 而IntroductionAdvisor主要是引入新的接口到Targets对象中。

public interface PointcutAdvisor {Pointcut getPointcut();Advice getAdvice();
}

1、 PointcutAdvisor: Advice和Pointcut,默认实现为DefaultPointcutAdvisor, 还有NameMatchMethodPointcutAdvisor,RegexpMethodPointcutAdvisor等。 

 其中NameMacthMethodPointCutAdvisor、RegexpMethodPointCutAdvisor 可以对比常用的PointCut类有NameMatchedMethodPointCut和JdkRegexMethodPointCut。
 前者需要注入mappedName和advice属性,后者需要注入pattern和advice属性。其中mappedName和pattern是直接配置的值,而advice需要自己实现具体的advice,可见实现advisor的时候,不需要实现PointCut,一般PointCut只需要配置就好了,不需要具体实现类
 mappedName指明了要拦截的方法名,pattern按照正则表达式的方法指明了要拦截的方法名,advice定义了一个增强(需要自己实 现MethodBeforeAdvice、  MethodAfterAdvice、ThrowsAdvice、MethodInterceptor接口之 一)。然后在ProxyFactoryBean的拦截器(interceptorNames)中注入这个PointCutAdvisor即可,如上面这个ProxyFactoryBean是一个静态代理,只能代理一个类给加上AOP,那么这个静态代理需要注入有目标对象,目标对象的接口,和interceptorsNames

2、 IntroductionAdvisor :默认实现为DefaultIntroductionAdvisor,这个主要与Introduction有关,可以参考上面的例子


  — 目标对象(Target Object):包含连接点的对象,也被称作被通知或被代理对象。

  — AOP代理(AOP Proxy):AOP框架创建的对象,包含通知。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。如ProxyFactory,ProxyFactoryBean, 下面会进行详细说明    

  — 编织(Weaving):组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。将Aspect加入到程序代码的过程,对于Spring AOP,由ProxyFactory或者ProxyFactoryBean负责织入动作。 

    通过ProxyFactory可以将对符合条件的类调用时添加上Aspect。

    或者 可使用XML声明式 ProxyFactoryBean:需要设定 target,interceptorNames(可以是Advice或者Advisor,注意顺序, 对接口代理需设置proxyInterfaces 

注意:一个ProxyFactoryBean只能指定一个代理目标,不是很方便,这就产生了自动代理。通过自动代理,可以实现自动为多个目标Bean实现AOP代理、避免客户端直接访问目标Bean(即getBean返回的都是Bean的代理对象)。spring的自动代理是通过BeanPostProcessor实现的,容器载入xml配置后会修改bean为代理Bean,而id不变。 

ApplicationContext可以直接检测到定义在容器中的BeanPostProcessor,BeanFactory需要手动添加。 
有2种常用的BeanPostProcessor: 
1.BeanNameAutoProxyCreator 故名思议,BeanName需要注入的两个属性有BeanNames和interceptorNames

<bean id="loginBeforeAdvisor" .../>  
<bean id="loginThrowsAdvisor" .../>  
<bean  class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">  <!-- 注入目标Bean -->  <property name="beanNames" value="*Service">  </property>  <property name="interceptorNames">  <list>  <value>loginBeforeAdvisor</value>  <value>loginThrowsAdvisor</value>  </list>  </property>  
</bean>  

2.DefaultAdvisorAutoProxyCreator: DefaultAdvisorAutoProxyCreator和BeanNameAutoProxyCreator不同的是,前者只和Advisor 匹配, 该类实现了BeanPostProcessor接口。当应用上下文读入所有的Bean的配置信息后,该类将扫描上下文,寻找所有的Advisor,他将这些Advisor应用到所有符合切入点的Bean中。所以下面的xml中没有绑定也无需绑定DefaultAdvisorAutoProxyCreator与Advisor的关系。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans><bean id="kwikEMartTarget" class="demo.ApuKwikEMart"></bean><bean id="performanceThresholdInterceptor" class="demo.advice.PerformanceThresholdInterceptor"><constructor-arg><value>5000</value></constructor-arg></bean><!-- 使用RegexpMethodPointcutAdvisor来匹配切入点完成个一个Advisor; --><bean id="regexpFilterPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><property name="pattern"><!-- 匹配的名字为方法名--><value>.*buy.*</value></property><property name="advice"><ref bean="performanceThresholdInterceptor"/></property></bean><bean id="defaultAdvisorAutoProxyCreator"class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
</beans>

在使用Aonnotation的时候,需要进行在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"xmlns:aop="http://www.springframework.org/schema/aop"      xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/beans/spring-aop-3.0.xsd"><!-- 启动对@AspectJ注解的支持 --><aop:aspectj-autoproxy/>
</beans>


综上,Spring下AOP的配置与实现,BeanNameAutoProxyCreator,DefaultAdvisorAutoProxyCreator已经部分简化了AOP配置,然而还是很繁琐: 首先要编写xxxAdvice类(需要自己实现MethodBeforeAdvice、MethodAfterAdvice、 ThrowsAdvice、MethodInterceptor接口之一),然后还要在xml中配置Advisor,还要在Advisor中注入 Advice,最后还要将Advisor加入ProxyFactoryBean、BeanNameAutoProxyCreator或者 DefaultAdvisorAutoProxyCreator中

实际上AOP不止Spring进行了实现,还有AspectJ,后者对AOP中的概念实现比较彻底,可以看上面,而Spring中对AOP的方方面面进行简化,拿上面定义的regexpFilterPointcutAdvisor是一种Advisor包含了PointCut和Advice,而此处的PointCut就是pattern属性的值了,没有特定的PointCut Bean定义,而advice定义了Bean。而其他概念Aspect, JoinPoint都融汇于Advice的实现中即Advisor(MethodBeforeAdvice等和MethodIntector接口的实现类)或IntroductionInterceptor了




较详细的介绍AOP  http://blog.chinaunix.net/uid-21547257-id-97998.html

利用Spring Interceptor 来缓存指定方法结果:  http://www.blogjava.net/kapok/archive/2005/04/17/3388.html
Advice的类型及实现细节: http://blog.csdn.net/saintlu/article/details/3340190

http://www.cnblogs.com/tazi/articles/2306160.html  

http://blog.csdn.net/a906998248/article/details/7514969

http://sishuok.com/forum/blogPost/list/2466.html;jsessionid=AC7C2BDCBF5B19BE4327AD26D40C3CFF


http://chatgpt.dhexx.cn/article/Y0Zd8gNV.shtml

相关文章

spring AOP 原理

一、spring注册 AnnotationAwareAspectJAutoProxyCreator 通过EnableAspectJAutoProxy可以看到先把AspectJAutoProxyRegistrar通过Import注册到spring。 AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口&#xff0c;所以就有了将某个bean引入spring 的能力…

Spring的AOP实现原理

本学习笔记将尽可能的将AOP的知识讲解的通俗易懂&#xff0c;先从一个典型的问题出发&#xff0c;引入AOP这个概念&#xff0c;介绍AOP的基本概念&#xff0c;再到Spring中的AOP的实现方案&#xff0c;最后进行一个简单的总结归纳。本学习笔记中不考虑cglib、也不会太关注Sprin…

spring的AOP和IOC的原理

目录 一、spring的ioc与aop原理 二、代理模式&#xff1a; 三、静态代理 四、动态代理 五、实际的操作 六、动态代理的实现&#xff1a; 七、什么是AOP 八、主流的AOP框架&#xff1a; 九、术语&#xff1a; 十、通知的五种类型&#xff1a; 十一、AOP的优点&#x…

spring aop原理

&#x1f345; Java学习路线&#xff1a;搬砖工逆袭Java架构师 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、CSDN哪吒公众号作者✌ 、Java架构师奋斗者&#x1f4aa; &#x1f345; 扫描主页左侧二维码&#xff0c;加入群聊&#xff0c;一起学习、一起进步…

AOP原理

AOP原理 什么是AopAOP的作用AOP的基本概念AOP使用场景AOP原理如何动态修改功能AOP的编程思想AOP面向切面编程操作AOP通知执行的顺序代码执行流程准备工作源码揭开面纱 什么是Aop AOP&#xff08;Aspect Orient Programming&#xff09;也就是面向切面编程&#xff0c;作为面向对…

无法显示页面,因为发生内部服务器错误。

用iis添加网站后&#xff0c;访问域名&#xff0c;显示“无法显示页面&#xff0c;因为发生内部服务器错误。” 之前我将这些文件放在一个Demo文件夹中&#xff0c;把Demo放在test站点下&#xff0c;通过域名访问Demo报错。 我将Demo下的文件直接放在test下&#xff0c;访问成…

遇到“服务器内部错误http500怎么办?

出现500错误的原因是很多的&#xff0c;一般来说都是程序错误导致的&#xff0c;如果程序出错&#xff0c;那么在浏览器内会返回给用户一个友好的错误提示&#xff0c;统一称之为服务器500错误。 解决的方法就是您必须在http中能够正确的获得错误信息&#xff0c;方法为&#x…

500 - 内部服务器错误--解决方案

一般网上的方法是这样的&#xff1a; 一、打开 Internet 信息服务(IIS)管理器。点击出错的站点&#xff0c;并双击右边的ASP图标&#xff0c;如下图所示&#xff1a; 二、展开右侧配置中的“调试属性”&#xff0c;把“将错误发送到浏览器”的值设为 "true"&#xf…

HTTP状态 500 - 内部服务器错误 类型 异常报告,初学servlet遇到的问题

写给自己看&#xff0c;初学记录一下&#xff0c;maven项目中tomcat,Servlet遇到的问题 HTTP状态 500 - 内部服务器错误 类型 异常报告&#xff0c;初学servlet遇到的问题 类似这种报错&#xff0c;在hello world级别的servlet中碰到。 报错分析 大概是说自定义java类在实例…

IIS 配置网站出现500内部服务器错误,显示具体错误信息

1、打开IIS 找到如下图的部分&#xff0c;双击点开 2、点开之后找到如下图部分&#xff0c;点击 3、选择如下图部分&#xff0c;然后点击确定。 4、这个时候页面会出现详细的错误&#xff0c;如果没有出现详细错误&#xff0c;配置如下图部分&#xff0c;不勾选。 5、这时会出现…

Nextcloud 内部服务器错误解决

在部署nextcloud过程中最后登录页面时出现内部服务器错误&#xff0c;心态当时就炸了。 在网上找了各种方案&#xff0c;但是大部分博主都告诉我是/var/lib/php/session/属组的权限问题&#xff0c;或者web目录的权限不对。但是对我这个问题没有用。 我把他们的方案贴出来对你…

IDEA中HTTP500 - 内部服务器错误类型 在 [] 行处理 [/.jsp] 时发生异常情况;java.lang.NoSuchMethodError: com.Bean.Person.setId

问题&#xff1a; HTTP状态 500 - 内部服务器错误 类型 异常报告 消息 在 [65] 行处理 [/pages/el 5/elDataDemo2.jsp] 时发生异常 描述 服务器遇到一个意外的情况&#xff0c;阻止它完成请求。 例外情况 org.apache.jasper.JasperException: 在 [65] 行处理 [/pages/el 5/elDa…

HTTP状态 500 - 内部服务器错误:No converter found for return value of type: class xxx(简单分析及解决)

问题描述 以下内容基于ssm框架&#xff0c;当我们向tomcat服务器发起请求时&#xff0c;出现如下的错误状态提示–500。 Tomcat日志信息&#xff1a; 原因分析&#xff1a; 未找到类型返回值的转换器&#xff1a;类 com.ssm.utils.Msg&#xff0c;使用jackson绑定数据时出现…

阿里云服务器出错500 - 内部服务器错误

阿里云服务器部署并发布成功后&#xff0c;访问该网页时出错&#xff0c;报 500 - 内部服务器错误。 原因&#xff1a;1.http 500内部服务器错误说明IIS服务器无法解析ASP代码&#xff0c;如果你联网还发现找不到服务器就是500错误了. 2.在安装Framework v4.0之后&#xff0c…

HTTP 500 - Internal Server Error 服务器内部错误

php出现如下错误 原因是出现了中文字符 修改后&#xff0c;页面成功访问

500错误及服务器内部错误

500错误及服务器请求错误 一、简言&#xff1a;500错误代表着你请求的后端或者说服务器端出现了错误。 可能的原因非常多&#xff0c;因为很多程序内部都会把代码运行出现的错误捕捉然后直接返回一个“服务器内部错误500”&#xff0c;这也就导致了我们在前端发送请求时见到的…

远程服务器返回错误: (500) 内部服务器错误解决办法

在.net中发送 xml post请求和接受xml 的post请求时&#xff0c;经常会遇到“远程服务器返回错误: (500) 内部服务器错误”。 这里有2种解决办法&#xff1a; 第一种方法&#xff1a;修改请求端Content-Type 为“text/xml”(httpclient.Headers.Add("Content-Type",…

服务器错误500-内部服务器错误。您查找的资源存在问题,因而无法显示。

当我们用iis环境搭建的网站出现了服务器错误500错误时我们该怎么处理呢&#xff0c;小编的网站织梦网站就出现了服务器错误 500 - 内部服务器错误。 您查找的资源存在问题&#xff0c;因而无法显示这个问题&#xff0c;如下图所示。织梦网站后台登陆前台预览都是正常的&#x…

什么是HTTP 500内部服务器错误,要怎么修复

HTTP 500是一种原始的错误代码&#xff0c;它指示网站服务器在处理请求时发生了内部错误&#xff0c;不过具体错误原因是不确定的。一般情况下&#xff0c;这种错误通常是由服务器程序上的bug或者配置问题造成的。当服务器收到请求时&#xff0c;尝试执行它时&#xff0c;但是发…

HTTP状态500-内部服务器错误

SSM整合时出现的问题 起初关注点一直在Mapper.xml上&#xff0c;CSDN查询解决方法大致在这样几种。 1.SQL语句问题 2.resultType返回类型问题&#xff08;List集合中的参数类型&#xff09; 3.database.properties数据库配置文件问题&#xff08;Mysql8以上加时区&#xff0c;文…