Spring学习-初识Spring

这几天一直在看Spring.虽然已经看到了第3章,但是感觉没多大收获,所以我又回过头,再温习一下。

Spring是什么?

Spring是一个开源框架,最早由Rod Johnson创建,Spring是为了解决企业级应用开发的复杂性而创建的。Spring为企业级开发提供了丰富的功能,但是这些功能的底层都依赖于它的两个核心特性,依赖注入(deoendency injection,DI)和面向切面编程(aspect-oriented programming,AOP)。

为了降低Java开发的复杂性,Spring采取了以下四种关键策略:

  • 基于POJO的轻量级和最小侵入性编程;
  • 通过依赖注入和面向接口实现松耦合;
  • 基于切面和惯例进行声明式编程;
  • 通过切面和模版减少样板式代码;
DI-依赖注入:

组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中,依赖注入的目的是并非为软件系统带来更多的功能,而是为了提升组件重用的频率,并为系统搭建一个灵活的、可扩展的平台。
简单的说,对象不需要自行创建或管理它们的依赖关系,依赖关系将自动注入到需要它们的对象中。

AOP-面向切面编程:

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP能够确保POJO的简单性借助AOP,可以使用各种功能层去包裹核心业务层。这些层以声明的方式灵活的运用到系统中,核心应用甚至根本不知道它们的存在。

下面是一篇我认为挺好的关于AOP的讲解的博客:
https://blog.csdn.net/yanquan345/article/details/19760027
下面为代码示例:

package com.springinaction.knights;

public class DamselRescuingKnight implements Knight{
    private RescueDamselQuest quest;
    public DamselRescuingKnight(){
        this.quest = new RescueDamselQuest();
    }
    public void embarkOnQuest(){
        quest.embark();
    }
}

正如你所见,DamselRescuingKnight 在它的构造函数中自行创建了RescueDamselQuest,这使得DamselRescuingKnight和RescueDamselQuest紧密地耦合到了一起,为这个DamselRescuingKnight编写测试比较困难。因为在测试中,你必须保证当骑士的embarkOnQuest()方法被调用的时候,探险的embark()方法也要被调用。但是没有一个简单明了的方式能够实现这一点。所以,DamselRescuingKnigh将无法进行测试。

对于这个无法测试,网上有人这样说:
耦合性也称块间联系。指软件系统结构中各模块间相互联系紧密程度的一种度量。模块之间联系越紧密,其耦合性就越强,模块的独立性则越差。
高耦合的模块说明外部的依赖比较多。
进行测试的需要准备好依赖模块。
依赖模块还有不同的状态及不确定性。
多个依赖模块不同状态排列组合后,放大了不确定性。
不能确定测试出来的结果是否正确。

虽然这样说,但还是不明了,这块暂时还是我的一个疑问,先暂留记号,日后会再来补充。

为了避免以上这种情况,我们可以通过可以通过依赖注入的方式来完成对象之间的依赖关系,对象不再需要自行管理它们的依赖关系,而是通过依赖注入自动地注入到对象中去。

package com.springinaction.knights;

public class BraveKnight  implements Knight{
    private Quest quest;

    public BraveKnight(Quest quest){//quest被注入进来
        this.quest = quest;
    }
    public void embarkOnQuest() {
        quest.embark();
    }
}

不同于之前的DamselRescuingKnight,BraveKnight没有自行创建探险任务,而是在构造器中把探险任务作为参数传入,这是依赖注入的一种方式,即构造器注入。更为重要的是,BraveKnight中注入的探险类型是Quest,Quest只是一个探险任务所必须实现的接口。因此,BraveKnight能够响RescueDamselQuest、SlayDraonQuest等任意一种Quest实现。

这里的要点是BraveKnight没有与任何特定的Quest实现发生耦合。对它来说,被要求挑战的探险任务只要实现了Quest接口,那么具体是哪一类型的探险就无关紧要了。这就是依赖注入最大的好处–松耦合。如果一个对象只通过接口(而不是具体实现或初始化的过程)来表明依赖关系,那么这种依赖就能够在对象本身毫不知情的情况下,用不同的具体实现进行替换。

这样就可以方便的实现测试(使用mock实现对依赖进行替换):

package com.springinaction.knights;

import org.junit.Test;

import static org.mockito.Mockito.*;

public class BraveKnightTest {
    @Test
    public void knightShouldEmbarkOnQuest(){
        Quest mockQuest = mock(Quest.class);//创建mock Quest
        BraveKnight knight = new BraveKnight(mockQuest);//注入mock Quest
        knight.embarkOnQuest();
        verify(mockQuest, times(1)).embark();//要求Mockito框架验证Ques的mock实现的embark()方法仅仅被调用一次。
    }
}

这里使用mock框架Mockito去创建一个Quest接口的mock实现。
这里用到的Quest接口如下:

package com.springinaction.knights;

public interface Quest {
    void embark();
}
注入一个Quest到Knight

创建应用组件之间协作关系的行为称为装配,Spring有多种装配Bean的方式,其中最常用的就是通过XML配置文件的方式装配。
示例代码:SlayDragonQuest实现Quest接口。

package com.springinaction.knights;

import java.io.PrintStream;

public class SlayDragonQuest implements Quest {
    private PrintStream stream;
    public SlayDragonQuest(PrintStream stream){
        this.stream = stream;
    }
    public void embark(){
        stream.println("Embarking on quest to slay the dragon!");
    }
}

SlayDragonQuest在这里使用了PrintStream,那我恩该如何将SlayDragonQuest交给BraveKnight呢?以及如何将PrintStream交给SlayDragonQuest?

这里使用Spring配置文件:knights.xml,将BraveKnight、SlayDragonQuestt和PrintStream装配到一起。

<?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="knight" class="com.springinaction.knights.BraveKnight">
           <constructor-arg ref="quest"/>
       </bean>
       <bean id="quest" class="com.springinaction.knights.SlayDragonQuest">
           <constructor-arg value="#{T{System).out}" />
</beans>

Spring通过应用上下文(ApplicationContext)来装载Bean,ApplicationContext全权负责对象的创建和组装。Spring自带了多种ApplicationContext来加载配置,因为knights.xml中的bean是使用XML文件进行配置的,所以选择ClassPathXmlApplicationContext作为应用上下文来加载位于应用程序路径下的一个或多个XML配置文件。

ApplicationContext三种经常用到的实现

  • ClassPathXmlApplicationContext:从类路径中加载。
  • FileSystemXmlApplicationContext:从文件系统加载。
  • XmlWebApplicationContext:从Web系统中加载。
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class KnightMain {
    public static void main(String[] args)throws Exception{
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/knights.xml");//使用 ClassPathXmlApplicationContext加载knights.xml
        Knight knight = context.getBean(Knight.class);   //获取knight bean
        knight.embarkOnQuest();  //使用knight
        context.close();
    }
}

该例中,应用上下文加载了knights.xml文件,随后获取了一个ID为knight的Bean的实例,得到knight对象的引用后,只需要简单的调用embarkOnQuest()方法就可以执行所赋予的探险任务了。注意这个类并不知道这是有BraveKnight来执行的。只有knights.xml文件知道那个骑士执行哪种探险任务。

AOP应用:

继续应用上面的例子,现在需要诗人这个服务类(Minstrel)来记载骑士的所有事迹。

package com.springinaction.knights;

import java.io.PrintStream;

public class Minstrel {
    private PrintStream stream;
    public Minstrel(PrintStream stream){
        this.stream = stream;
    }
    public void singBeforeQuest(){  //探险之前调用
        stream.println("Fa la la, the knight is so brave!");
    }
    public void singAfterQuest(){   //探险之后调用
        stream.println("Tee hee hee, the brave knight "+"did embark on a quest!");
    }
}

在探险前后,Minstrel都会通过一个PrinStream类来歌颂骑士的事迹,这个类是通过构造器注入进来的。
接下来,尝试把BraveKnight和Minstrel组合起来。

package com.springinaction.knights;

public class BraveKnight  implements Knight{
    private Quest quest;
    private Minstrel minstrel;

    public BraveKnight(Quest quest, Minstrel minstrel){
        this.quest = quest;
        this.minstrel = minstrel;
    }
    public void embarkOnQuest() {
        minstrel.singBeforeQuest();
        quest.embark();
        minstrel.singAfterQuest();
    }
}

这样,就不是诗人主动地为骑士传扬事迹。而且因为骑士需要知道吟咏诗人,所以就必须把诗人注入到BraveKnight类中,这使简单的BraveKnight类开始变得复杂,如果Minstrel为null,会发生什么?是否还得一个空值效验避免此场景?如果还需要应对没有吟咏诗人的场景,那代码会变得更加复杂。此时就需要AOP,你可以去声明吟咏诗人必须歌颂骑士的探险事迹,而骑士本身并不用直接访问Minstrel的方法。
下面即为在knights.xml中将Minstrel声明为一个切面。

<?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/aop
       http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="quest" class="com.springinaction.knights.SlayDragonQuest">
        <constructor-arg value="#{T(System).out}"/>
    </bean>

    <bean id="knight" class="com.springinaction.knights.BraveKnight">
        <constructor-arg ref="quest"/>
    </bean>

    <bean id="minstrel" class="com.springinaction.knights.Minstrel">
        <constructor-arg value="#{T(System).out}"/>
    </bean>
    <aop:config>
        <aop:aspect ref="minstrel">
            <aop:pointcut id="embark"
                          expression="execution(* *.embarkOnQuest(..))"/> <!--定义切点-->
            <aop:before pointcut-ref="embark"
                        method="singBeforeQuest"/>
            <aop:after pointcut-ref="embark"
                       method="singAfterQuest"/>
        </aop:aspect>
    </aop:config>
</beans>

这样更新knights.xml后,BraveKnight就不需要更改成上上一个代码那样了,保持如下这样即可

package com.springinaction.knights;

public class BraveKnight  implements Knight{
    private Quest quest;

    public BraveKnight(Quest quest){//quest被注入进来
        this.quest = quest;
    }
    public void embarkOnQuest() {
        quest.embark();
    }
}

这样Minstrel可以被应用到BraveKnight中,而BraveKnight不需要显式的调用它。BraveKnight完全不知道Minstrel的存在。
最后隆重出场的是我们的测试类:

package com.springinaction.knights;

import org.junit.Test;

import static org.mockito.Mockito.*;

public class BraveKnightTest {
    @Test
    public void knightShouldEmbarkOnQuest(){
        Quest mockQuest = mock(Quest.class);
        BraveKnight knight = new BraveKnight(mockQuest);
        knight.embarkOnQuest();
        verify(mockQuest, times(1)).embark();
    }
}

运行结果:
Spring学习-初识Spring_第1张图片

在运行中还遇到一个问题,错误显示如下
解决方法: 在pom.xml加入如下一段:(即下载并导入 aspectjweaver-1.6.9.jar 包)

        
             org.aspectj
             aspectjweaver
            1.6.9
        
/usr/lib/jvm/jdk1.8.0_172/bin/java -javaagent:/usr/local/idea-IU-183.5153.38/lib/idea_rt.jar=39003:/usr/local/idea-IU-183.5153.38/bin -Dfile.encoding=UTF-8 -classpath /usr/lib/jvm/jdk1.8.0_172/jre/lib/charsets.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/deploy.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/ext/cldrdata.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/ext/dnsns.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/ext/jaccess.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/ext/jfxrt.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/ext/localedata.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/ext/nashorn.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/ext/sunec.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/ext/zipfs.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/javaws.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/jce.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/jfr.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/jfxswt.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/jsse.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/management-agent.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/plugin.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/resources.jar:/usr/lib/jvm/jdk1.8.0_172/jre/lib/rt.jar:/home/ltt/IdeaProjects/study_Spring/target/classes:/home/ltt/IdeaProjects/libtt/spring-context-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-beans-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-aop-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-aspects-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-context-support-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-core-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-instrument-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-expression-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-instrument-tomcat-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-jdbc-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-jms-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-messaging-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-orm-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-oxm-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-test-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/spring-tx-4.3.18.RELEASE.jar:/home/ltt/IdeaProjects/libtt/commons-logging-1.2.jar:/home/ltt/IdeaProjects/libtt/aopalliance-1.0.jar com.springinaction.knights.KnightMain
三月 31, 2019 9:51:58 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@46f7f36a: startup date [Sun Mar 31 21:51:58 CST 2019]; root of context hierarchy
三月 31, 2019 9:51:59 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [META-INF/knights.xml]
三月 31, 2019 9:51:59 下午 org.springframework.context.support.ClassPathXmlApplicationContext refresh
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quest' defined in class path resource [META-INF/knights.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0': Cannot create inner bean '(inner bean)#1d16f93d' of type [org.springframework.aop.aspectj.AspectJMethodBeforeAdvice] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1d16f93d': Cannot resolve reference to bean 'embark' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'embark': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.AspectJExpressionPointcut]: No default constructor found; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/tools/PointcutDesignatorHandler
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quest' defined in class path resource [META-INF/knights.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0': Cannot create inner bean '(inner bean)#1d16f93d' of type [org.springframework.aop.aspectj.AspectJMethodBeforeAdvice] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1d16f93d': Cannot resolve reference to bean 'embark' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'embark': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.AspectJExpressionPointcut]: No default constructor found; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/tools/PointcutDesignatorHandler
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:479)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
	at com.springinaction.knights.KnightMain.main(KnightMain.java:7)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0': Cannot create inner bean '(inner bean)#1d16f93d' of type [org.springframework.aop.aspectj.AspectJMethodBeforeAdvice] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1d16f93d': Cannot resolve reference to bean 'embark' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'embark': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.AspectJExpressionPointcut]: No default constructor found; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/tools/PointcutDesignatorHandler
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:313)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:129)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:648)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:145)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1201)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1103)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(BeanFactoryAdvisorRetrievalHelper.java:92)
	at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findCandidateAdvisors(AbstractAdvisorAutoProxyCreator.java:102)
	at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:103)
	at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(AbstractAutoProxyCreator.java:248)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1045)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1019)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:473)
	... 10 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1d16f93d': Cannot resolve reference to bean 'embark' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'embark': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.AspectJExpressionPointcut]: No default constructor found; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/tools/PointcutDesignatorHandler
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:634)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:145)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1201)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1103)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299)
	... 28 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'embark': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.AspectJExpressionPointcut]: No default constructor found; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/tools/PointcutDesignatorHandler
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1163)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1107)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:331)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
	... 36 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.AspectJExpressionPointcut]: No default constructor found; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/tools/PointcutDesignatorHandler
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1155)
	... 42 more
Caused by: java.lang.NoClassDefFoundError: org/aspectj/weaver/tools/PointcutDesignatorHandler
	at java.lang.Class.getDeclaredConstructors0(Native Method)
	at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
	at java.lang.Class.getConstructor0(Class.java:3075)
	at java.lang.Class.getDeclaredConstructor(Class.java:2178)
	at org.
	.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
	... 43 more
Caused by: java.lang.ClassNotFoundException: org.aspectj.weaver.tools.PointcutDesignatorHandler
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 48 more



你可能感兴趣的:(Spring学习)