2022/5/2 Spring框架深入学习

目录

1.依赖注入方式扩展

        1.1 构造注入

                1.1.1 无参构造注入

                1.1.2 有参构造注入

                1.1.3 c 命名空间注入

        1.2 set注入 (重点)

                1.2.1 常量注入

                1.2.2 Bean注入

                1.2.3 数组注入

                1.2.4 List注入

                1.2.5 Map注入

                1.2.6 set注入

                1.2.7 Null注入

                1.2.8 Properties注入

                1.2.9 P命名空间注入

                1.2.10 测试结果

                 1.2.11 XML文件中特殊符号与实体引用的对应关系

2.使用注解实现Spring IoC

        2.1 Bean的自动装配

                2.1.1 测试环境搭建

                2.1.2 byName

                2.1.3 byType

        2.2 自动装配注解

                2.2.1  @Autowired

                2.2.2 @Qualifier

                2.2.3 @Resource

                2.2.4 小结

        2.3 Bean的实现

         2.4 属性注入

        2.5 衍生注解

        2.6 作用域

        2.7 小结

         2.8 基于Java类进行配置

3.使用注解实现Spring AOP

        3.1 配置applicationContext.xml

        3.2 编写AOP类

        3.3 编写实体类

        3.4 编写测试类

        3.5 输出结果

4.本章总结


1.依赖注入方式扩展

  • 依赖注入(Dependency Injection,DI)。
  • 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 . 
  • 注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 .

        1.1 构造注入

                1.1.1 无参构造注入

1. User.java

public class User {
    private String name;
    public User() {
        System.out.println("user无参构造方法");
   }
    public void setName(String name) {
        this.name = name;
   }
    public void show(){
        System.out.println("name="+ name );
   }
}

2.beans.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="user" class="com.kuang.pojo.User">
        <property name="name" value="kuangshen"/>
    </bean>
</beans>

3. 测试类

@Test
public void test(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    //在执行getBean的时候, user已经创建好了 , 通过无参构造
    User user = (User) context.getBean("user");
    //调用对象的方法 .
    user.show();
}

结果可以发现,在调用show方法之前,User对象已经通过无参构造初始化了!

                1.1.2 有参构造注入

1. UserT . java

public class UserT {
    private String name;
    public UserT(String name) {
        this.name = name;

    }
    public void setName(String name) {
        this.name = name;
   }
    public void show(){
        System.out.println("name="+ name );
   }
}

2.beans.xml 有三种方式编写

<!-- 第一种根据index参数下标设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
    <!-- index指构造方法 , 下标从0开始 -->
    <constructor-arg index="0" value="kuangshen2"/>
</bean>
<!-- 第二种根据参数名字设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
    <!-- name指参数名 -->
    <constructor-arg name="name" value="kuangshen2"/>
</bean>
<!-- 第三种根据参数类型设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
    <constructor-arg type="java.lang.String" value="kuangshen2"/>
</bean>

3. 测试

@Test
public void testT(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    UserT user = (UserT) context.getBean("userT");
    user.show();
}

结论:在配置文件加载的时候。其中管理的对象都已经初始化了!

                1.1.3 c 命名空间注入

导入约束 : xmlns:c="http://www.springframework.org/schema/c"
<!--C(构造: Constructor)命名空间 , 属性依然要设置set方法-->
<bean id="user" class="com.kuang.pojo.User" c:name="狂神" c:age="18"/>

注意:c 就是所谓的构造器注入,如果没有空参构造器此方法会报错!

        1.2 set注入 (重点)

要求被注入的属性 , 必须有set方法 , set方法的方法名由set + 属性首字母大写 , 如果属性是boolean类型 , 没有set方法 , 是 is .
测试pojo类 :

Address.java

public class Address {
    private String address;
    public String getAddress() {
        return address;
   }
    public void setAddress(String address) {
        this.address = address;
   }
}

Student.java

package com.kuang.pojo;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbys;
    private Map<String,String> card;
    private Set<String> games;
    private String wife;
    private Properties info;
    public void setName(String name) {
        this.name = name;
       }
    public void setAddress(Address address) {
        this.address = address;
       }
    public void setBooks(String[] books) {
        this.books = books;
       }
    public void setHobbys(List<String> hobbys) {
        this.hobbys = hobbys;
       }
    public void setCard(Map<String, String> card) {
        this.card = card;
       }
    public void setGames(Set<String> games) {
        this.games = games;
       }
    public void setWife(String wife) {
        this.wife = wife;
       }
    public void setInfo(Properties info) {
        this.info = info;
       }
    public void show(){
        System.out.println("name="+ name
                + ",address="+ address.getAddress()
                + ",books="
       );
        for (String book:books){
            System.out.print("<<"+book+">>\t");
       }
        System.out.println("\n爱好:"+hobbys);
        System.out.println("card:"+card);
        System.out.println("games:"+games);
        System.out.println("wife:"+wife);
        System.out.println("info:"+info);
   }
}

                1.2.1 常量注入

<bean id="student" class="com.kuang.pojo.Student">
    <property name="name" value="小明"/>
</bean>

                1.2.2 Bean注入

注意点:这里的值是一个引用,ref

<bean id="addr" class="com.kuang.pojo.Address">
    <property name="address" value="重庆"/>
</bean>
<bean id="student" class="com.kuang.pojo.Student">
    <property name="name" value="小明"/>
    <property name="address" ref="addr"/>
</bean>

                1.2.3 数组注入

<bean id="student" class="com.kuang.pojo.Student">
    <property name="name" value="小明"/>
    <property name="address" ref="addr"/>
    <property name="books">
        <array>
            <value>西游记</value>
            <value>红楼梦</value>
            <value>水浒传</value>
        </array>
    </property>
</bean>

                1.2.4 List注入

<property name="hobbys">
    <list>
        <value>听歌</value>
        <value>看电影</value>
        <value>爬山</value>
    </list>
</property>

                1.2.5 Map注入

<property name="card">
    <map>
        <entry key="中国邮政" value="456456456465456"/>
        <entry key="建设" value="1456682255511"/>
    </map>
</property>

                1.2.6 set注入

<property name="games">
    <set>
        <value>LOL</value>
        <value>BOB</value>
        <value>COC</value>
    </set>
</property>

                1.2.7 Null注入

<property name="wife"><null/></property>

                1.2.8 Properties注入

<property name="info">
    <props>
        <prop key="学号">20190604</prop>
        <prop key="性别">男</prop>
        <prop key="姓名">小明</prop>
    </props>
</property>

                1.2.9 P命名空间注入

导入约束 : xmlns:p="http://www.springframework.org/schema/p"
<!--P(属性: properties)命名空间 , 属性依然要设置set方法-->
<bean id="user" class="com.kuang.pojo.User" p:name="狂神" p:age="18"/>

                1.2.10 测试结果

                 1.2.11 XML文件中特殊符号与实体引用的对应关系

符号实体引用
&&amp;
<&lt;
>&gt;
&apos;
&quot;

2.使用注解实现Spring IoC

        2.1 Bean的自动装配

  • 自动装配是使用spring满足bean依赖的一种方法
  • spring会在应用上下文中为某个bean寻找其依赖的bean。

Spring中bean有三种装配机制,分别是:

  1. 在xml中显式配置; 
  2. 在java中显式配置; 
  3. 隐式的bean发现机制和自动装配。

这里我们主要讲第三种:自动化的装配bean。

Spring的自动装配需要从两个角度来实现,或者说是两个操作: 

  1. 组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean; 
  2. 自动装配(autowiring):spring自动满足bean之间的依赖,也就是我们说的IoC/DI;

组件扫描和自动装配组合发挥巨大威力,使的显示的配置降低到最少。
推荐不使用自动装配xml配置 , 而使用注解 .

                2.1.1 测试环境搭建

1.新建一个项目

2.新建两个实体类,Cat  Dog  都有一个叫的方法

public class Cat {
    public void shout() {
        System.out.println("miao~");
   }
}
public class Dog {
    public void shout() {
        System.out.println("wang~");
   }
}

3. 新建一个用户类 User

public class User {
    private Cat cat;
    private Dog dog;
    private String str;
}

4.编写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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="dog" class="com.kuang.pojo.Dog"/>
    <bean id="cat" class="com.kuang.pojo.Cat"/>
    <bean id="user" class="com.kuang.pojo.User">
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
        <property name="str" value="qinjiang"/>
    </bean>
</beans>

5. 测试

public class MyTest {
    @Test
    public void testMethodAutowire() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        User user = (User) context.getBean("user");
        user.getCat().shout();
        user.getDog().shout();
   }
}

结果正常输出,环境OK


                2.1.2 byName

autowire byName (按名称自动装配)

由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。
采用自动装配将避免这些错误,并且使配置简单化。

测试:

        1. 修改bean配置,增加一个属性 autowire="byName"

<bean id="user" class="com.kuang.pojo.User" autowire="byName">
    <property name="str" value="qinjiang"/>
</bean>

        2. 再次测试,结果依旧成功输出!
        3. 我们将 cat 的bean id修改为 catXXX
        4. 再次测试, 执行时报空指针java.lang.NullPointerException。因为按byName规则找不对应set方法,真正的setCat就没执行,对象就没有初始化,所以调用时就会报空指针错误。

小结:

当一个bean节点带有 autowire byName的属性时。
        1. 将查找其类中所有的set方法名,例如setCat,获得将set去掉并且首字母小写的字符串,即cat。
        2. 去spring容器中寻找是否有此字符串名称id的对象。
        3. 如果有,就取出注入;如果没有,就报空指针异常。

                2.1.3 byType

autowire byType (按类型自动装配)

使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一的异常。

NoUniqueBeanDefinitionException

测试:

  1. 将user的bean配置修改一下 : autowire="byType"
  2. 测试,正常输出
  3. 在注册一个cat 的bean对象!
    <bean id="dog" class="com.kuang.pojo.Dog"/>
    <bean id="cat" class="com.kuang.pojo.Cat"/>
    <bean id="cat2" class="com.kuang.pojo.Cat"/>
    <bean id="user" class="com.kuang.pojo.User" autowire="byType">
        <property name="str" value="qinjiang"/>
    </bean>
  4. 测试,报错:NoUniqueBeanDefinitionException

  5. 删掉cat2,将cat的bean名称改掉!测试!因为是按类型装配,所以并不会报异常,也不影响最后
    的结果。甚至将id属性去掉,也不影响结果。

这就是按照类型自动装配!

        2.2 自动装配注解

jdk1.5开始支持注解,spring2.5开始全面支持注解。
准备工作: 利用注解的方式注入属性。
        1. 在spring配置文件中引入context文件头

xmlns:context="http://www.springframework.org/schema/context"

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

        2. 开启属性注解支持!

        <!--扫描包名支持注解-->
         <context:component-scan base-package="entity,aop"/>
        <!--支持aop注解-->
         <context:annotation-config/>
        <!--支持aop切面注解-->
        <aop:aspectj-autoproxy/>

                2.2.1  @Autowired

  • @Autowired是按类型自动转配的,不支持id匹配。
  • 需要导入 spring-aop的包!

测试:

        1. 将User类中的set方法去掉,使用@Autowired注解

public class User {
    @Autowired
    private Cat cat;
    @Autowired
    private Dog dog;
    private String str;
    public Cat getCat() {
        return cat;
   }
    public Dog getDog() {
        return dog;
   }
    public String getStr() {
        return str;
   }
}

        2. 此时配置文件内容

<context:annotation-config/>
<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User"/>

        3. 测试,成功输出结果!

科普:

@Autowired(required=false) 说明: false,对象可以为null;true,对象必须存对象,不能为null。

//如果允许对象为null,设置required = false,默认为true
@Autowired(required = false)
private Cat cat;

                2.2.2 @Qualifier

  • @Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
  • @Qualifier不能单独使用。

测试实验步骤:

        1. 配置文件修改内容,保证类型存在对象。且名字不为类的默认名字!

<bean id="dog1" class="com.kuang.pojo.Dog"/>
<bean id="dog2" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>

        2. 没有加Qualifier测试,直接报错
        3. 在属性上添加Qualifier注解

@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;

        4. 测试,成功输出!

                2.2.3 @Resource

  • @Resource如有指定的name属性,先按该属性进行byName方式查找装配;
  • 其次再进行默认的byName方式进行装配;
  • 如果以上都不成功,则按byType的方式自动装配。
  • 都不成功,则报异常。

实体类:

public class User {
    //如果允许对象为null,设置required = false,默认为true
    @Resource(name = "cat2")
    private Cat cat;
    @Resource
    private Dog dog;
    private String str;
}

beans.xml

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User"/>

测试:结果OK

配置文件2:beans.xml , 删掉cat2

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>

实体类上只保留注解

@Resource
private Cat cat;
@Resource
private Dog dog;

结果:OK
结论:先进行byName查找,失败;再进行byType查找,成功。

                2.2.4 小结

@Autowired与@Resource异同:

  1. @Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。
  2. @Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
  3. @Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先
byName。

        2.3 Bean的实现

我们之前都是使用 bean 的标签进行bean注入,但是实际开发中,我们一般都会使用注解!

        1. 配置扫描哪些包下的注解

<!--指定注解扫描包-->
<context:component-scan base-package="com.kuang.pojo"/>

        2. 在指定包下编写类,增加注解

@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
    public String name = "秦疆";
}

        3. 测试

@Test
public void test(){
    ApplicationContext applicationContext =
        new ClassPathXmlApplicationContext("beans.xml");
    User user = (User) applicationContext.getBean("user");
    System.out.println(user.name);
}

         2.4 属性注入


使用注解注入属性

        1. 可以不用提供set方法,直接在直接名上添加@value("值")

@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
    @Value("秦疆")
    // 相当于配置文件中 <property name="name" value="秦疆"/>
    public String name;
}

        2. 如果提供了set方法,在set方法上添加@value("值")

@Component("user")
public class User {
    public String name;
    @Value("秦疆")
    public void setName(String name) {
        this.name = name;
   }
}

        2.5 衍生注解


我们这些注解,就是替代了在配置文件当中配置步骤而已!更加的方便快捷!
@Component三个衍生注解

为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。

  • @Controller:web层
  • @Service:service层
  • @Repository/@Mapper:dao层

写上这些注解,就相当于将这个类交给Spring管理装配了!

        2.6 作用域


@scope

  • singleton:默认的,Spring会采用单例模式创建这个对象。关闭工厂 ,所有的对象都会销毁。
  • prototype:多例模式。关闭工厂 ,所有的对象不会销毁。内部的垃圾回收机制会回收
@Controller("user")
@Scope("prototype")
public class User {
    @Value("Abcdzzr")
    public String name;
}

        2.7 小结

XML与注解比较

  • XML可以适用任何场景 ,结构清晰,维护方便
  • 注解不是自己提供的类使用不了,开发简单方便

xml与注解整合开发 :推荐最佳实践

  • xml管理Bean
  • 注解完成属性注入
  • 使用过程中, 可以不用扫描,扫描是为了类上的注解
    <context:annotation-config/>  
    

 作用:

  • 进行注解驱动注册,从而使注解生效
  • 用于激活那些已经在spring容器里注册过的bean上面的注解,也就是显示的向Spring注册
  • 如果不扫描包,就需要手动配置bean
  • 如果不加注解驱动,则注入的值为null!
     

         2.8 基于Java类进行配置

JavaConfig 原来是 Spring 的一个子项目,它通过 Java 类的方式提供 Bean 的定义信息,在 Spring4 的版本, JavaConfig 已正式成为 Spring4 的核心功能 。


测试:

        1. 编写一个实体类,Dog

@Component  //将这个类标注为Spring的一个组件,放到容器中!
public class Dog {
    public String name = "dog";
}

        2. 新建一个config配置包,编写一个MyConfig配置类

@Configuration  //代表这是一个配置类
public class MyConfig {
    @Bean //通过方法注册一个bean,这里的返回值就Bean的类型,方法名就是bean的id!
    public Dog dog(){
        return new Dog();
   }
}

        3.测试

@Test
public void test2(){
    ApplicationContext applicationContext =
            new AnnotationConfigApplicationContext(MyConfig.class);
    Dog dog = (Dog) applicationContext.getBean("dog");
    System.out.println(dog.name);
}

        4. 成功输出结果!

导入其他配置如何做呢?

        1. 我们再编写一个配置类!

@Configuration  //代表这是一个配置类
public class MyConfig2 {
}

        2.在之前的配置类中我们来选择导入这个配置类

@Configuration
@Import(MyConfig2.class)  //导入合并其他配置类,类似于配置文件中的 inculde 标签
public class MyConfig {
    @Bean
    public Dog dog(){
        return new Dog();
   }
}

关于这种Java类的配置方式,我们在之后的SpringBoot 和 SpringCloud中还会大量看到,我们需要知道
这些注解的作用即可!

3.使用注解实现Spring AOP

        3.1 配置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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       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/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">
        <!--扫描包名支持注解-->
         <context:component-scan base-package="entity,aop"/>
        <!--支持aop注解-->
         <context:annotation-config/>
        <!--支持aop切面注解-->
        <aop:aspectj-autoproxy/>
</beans>

        3.2 编写AOP类

package aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component//Component:相当于把这个类加载成了,bean标签
@Aspect //注解为切面
public class Myaop {
    @Before("pc()") //前置增强
    public void before(){
        System.out.println("玩蛇之前洗白白!");
    }

    @AfterReturning("pc()") //后置增强
    public void AfterReturning(){
        System.out.println("我是后置增强!");
    }
    @After("pc()") //最终增强
    public void After(){
        System.out.println("我是最终增强");
    }

    @Around("pc()")  //环绕增强:注意环绕增强不能和异常增强一起使用
    public void around(ProceedingJoinPoint pjp){
        System.out.println("我是前面的环绕增强!");
        try {
            pjp.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("我是后面的环绕增强!");
    }

   @AfterThrowing(value = "pc()",throwing = "e") //异常增强:注意环绕增强不能和异常增强一起使用
    public void error(Exception e){
        System.out.println("我是异常增强!");
    }
    @Pointcut("execution(public void Play())")
    public void pc(){

    }
}

        3.3 编写实体类

Master:

package entity;

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

import javax.annotation.Resource;

@Component//Component:相当于把这个类加载成了,bean标签
public class Master {
    /*@Autowired*/  //自动去ioc容器去寻找匹配的对象,前提是该对象已经在ioc容器中注册了  spring自带(按类型匹配)
    @Resource       //自动去ioc容器去寻找匹配的对象,前提是该对象已经在ioc容器中注册了  JDK自带(按名字匹配)
    private Snake s;
    /*@Autowired*/
    @Resource
    private Tiger t;

    public Snake getS() {
        return s;
    }

    public void setS(Snake s) {
        this.s = s;
    }

    public Tiger getT() {
        return t;
    }

    public void setT(Tiger t) {
        this.t = t;
    }
}

Snake:

package entity;

import org.springframework.stereotype.Component;

@Component//Component:相当于把这个类加载成了,bean标签
public class Snake {
    public void Play(){
        System.out.println("玩蛇!");
       /* throw new NullPointerException();*/
    }
}

Tiger:

package entity;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//Component:相当于把这个类加载成了,bean标签
@Component
public class Tiger {

    private int tid;
    private String tname;

    public int getTid() {
        return tid;
    }
    @Value("1")
    public void setTid(int tid) {
        this.tid = tid;
    }

    public String getTname() {
        return tname;
    }
    @Value("泰哥")
    public void setTname(String tname) {
        this.tname = tname;
    }
}

        3.4 编写测试类

package test;

import entity.Master;
import entity.Snake;
import entity.Tiger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Master master = ac.getBean("master", Master.class);
        System.out.println(master.getT().getTid());
        System.out.println(master.getT().getTname());
        master.getS().Play();
    }
}

        3.5 输出结果

log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
1
泰哥
我是前面的环绕增强!
玩蛇之前洗白白!
玩蛇!
我是后面的环绕增强!
我是最终增强
我是后置增强!

进程已结束,退出代码为 0

4.本章总结

  1. Spring框架提供了设置值注入丶构造注入等依赖注入方式。
  2. 在Spring配置文件中使用<context:component-scan base-package="xxx"/>扫描包含注解的类,完成初始化。
  3. 用来定义Bean组件的注解包括@Component丶@Repository丶@Mapper丶@Service丶@Controller。
  4. Bean组件的装配可以通过@Autowired丶@Qualifier或@Resource实现。
  5. 使用p命名空间可以简化属性注入的配置。
  6. 通过在配置文件中添加<aop:aspectj-autoproxy/>,就可以启用对@AspectJ注解的支持。
  7. Spring框架提供的增强处理方式主要包括前置增强丶后置增强丶异常抛出增强丶环绕增强丶最终增强等。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 学习 Spring 框架是一个很棒的选择!这是一个功能强大的 Java 框架,用于构建企业级应用程序。如果你是刚接触 Spring 框架,下面是一些提示来帮助你开始学习: 1. 了解 Spring 的核心概念:依赖注入,配置,事务管理等。 2. 阅读官方文档:了解 Spring 框架的各个组件的功能和使用方法。 3. 实践:构建一个简单的 Spring 应用程序并了解如何使用各种组件。 4. 学习常用技术:比如 Spring MVC,Spring Boot 等。 5. 深入学习:了解更高级的 Spring 知识,如安全,消息,持久性等。 希望这些信息能帮助你开始学习 Spring 框架!如果你需要进一步的帮助,可以随时询问我。 ### 回答2: 学习Spring框架是现代Java应用开发中非常重要的一部分。Spring是一个轻量级的开源框架,提供了丰富的功能和良好的可扩展性,使得开发者能够更加轻松地设计和构建复杂的应用程序。 首先,学习Spring框架能够帮助我们更好地使用依赖注入(DI)和控制反转(IOC)的概念。这两个概念使得开发者能够更好地管理程序之间的依赖关系,提高代码的可读性和可维护性。 其次,Spring框架提供了一系列的模块,例如AOP(面向切面编程)、JDBC(Java数据库连接)、ORM(对象关系映射)等,使得我们能够更加便捷地处理各种常见的任务和问题。我们可以利用AOP模块来处理横切关注点,使用JDBC模块来连接并操作数据库,利用ORM模块来映射Java对象和数据库之间的关系。 另外,Spring框架还与其他流行的开发框架和技术相结合,例如Hibernate、MyBatis、SpringMVC、Spring Boot等,使得我们能够更好地构建Web应用程序和服务。这些整合的模块和技术能够使我们更加高效地开发和部署应用程序。 最后,学习Spring框架也有助于我们更好地理解和应用面向对象(OOP)的原则和设计模式。Spring框架本身就是一个使用了许多设计模式的优秀示例,学习它能够帮助我们更好地设计和构建高质量的软件。 综上所述,学习Spring框架对于现代Java应用开发非常重要。通过学习Spring框架,我们可以更好地理解和应用依赖注入和控制反转的概念,利用框架提供的各种模块和技术更高效地开发应用程序,并且提升我们的面向对象编程能力。 ### 回答3: 学习Spring框架是一个非常有价值和重要的过程。Spring框架是一个开源的Java平台,用于开发企业级应用程序。它提供了一系列的功能,包括依赖注入、面向切面编程、声明式事务管理等。 学习Spring框架有以下几个方面的好处。首先,通过学习Spring框架,可以提高开发效率。Spring框架提供了丰富的功能和工具,可以简化开发过程,减少重复代码的编写,提高代码的复用性。其次,学习Spring框架可以使程序更加模块化和可测试。Spring框架倡导面向接口编程,通过依赖注入的方式进行组件的组装,使代码更加灵活和可扩展。再次,学习Spring框架可以提高系统的可维护性和可扩展性。Spring框架采用松耦合的设计思想,可以很方便地切换和替换各个组件,使系统更加灵活和易于维护。 学习Spring框架的过程中,可以利用官方文档、在线教程和书籍等各种资源。可以先从掌握基本概念和核心特性开始,如IoC容器、Bean、依赖注入等。然后,可以通过实际项目的开发来巩固和深入理解所学的知识。 除此之外,还可以参加相关的培训班或者社区活动,与其他开发者交流和分享经验。还可以通过参与开源项目和实践项目,来应用所学的知识,在实践中不断提高自己的技能。 总的来说,学习Spring框架是一个循序渐进的过程,需要不断地实践和提高。只有通过不断学习和实践,才能真正掌握和应用Spring框架的知识,从而提高自己的开发能力和竞争力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Abcdzzr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值