Spring 教程02

spring-2
1.    Xml

<!-- \src\applicationContext-annotation.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: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-4.0.xsd">

    <!-- 配置自动扫描的包 -->
    <context:component-scan base-package="com.atguigu.spring.ref"></context:component-scan>

</beans>

<!-- \src\applicationContext-aop.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"
    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/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- 自动扫描的包 -->
    <context:component-scan base-package="com.atguigu.spring.aop"></context:component-scan>

    <!-- 使 AspectJ 的注解起作用 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

<!-- \src\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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
        1. 默认情况下, IOC 容器中的 bean 是单例的! 若对象是单例的, 则在创建 IOC 容器时即创建 bean 的实例, 并对 bean 的属性进行初始化.
        2. 可以通过 bean 的 scope 属性来修改 bean 的作用域. 若取值为 prototype, 则 bean 为原型的: 每次向容器获取实例, 得到的都是一个新的对象.
        而且, 不在创建 IOC 容器时创建 bean 的实例了.
        3. IOC 容器中 bean 的生命周期:
        3.1 一般地, 讨论 bean 的生命周期, 是建立在 bean 是单例的基础上的.
        3.2 可以为 bean 指定 init 和 destroy 方法
        3.3 还可以通过 bean 的后置处理器来更加丰富 bean 的生命周期方法(面试时.).
    -->
    <bean id="helloWorld"
        class="com.atguigu.spring.helloworld.HelloWorld"
        scope="singleton"
        init-method="init"
        destroy-method="destroy">
        <property name="userName" value="atguigu"></property>
    </bean>

    <!--
        1. 在 IOC 容器中配置 bean 之间的关联关系
    -->
    <bean id="userDao"
        class="com.atguigu.spring.ref.UserDao"></bean>

    <bean id="userService"
        class="com.atguigu.spring.ref.UserService">
        <property name="userDao" ref="userDao"></property>
    </bean>

    <bean id="userAction"
        class="com.atguigu.spring.ref.UserAction">
        <property name="userService" ref="userService"></property>
    </bean>

</beans>
2.    Java

// \src\com\atguigu\spring\aop\ArithmeticCalculator.java
package com.atguigu.spring.aop;

public interface ArithmeticCalculator {

    int add(int i, int j);
    int sub(int i, int j);

    int mul(int i, int j);
    int div(int i, int j);

}

// \src\com\atguigu\spring\aop\ArithmeticCalculatorImpl.java
package com.atguigu.spring.aop;

import org.springframework.stereotype.Component;

@Component("arithmeticCalculator")
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {

    @Override
    public int add(int i, int j) {
        int result = i + j;
        return result;
    }

    @Override
    public int sub(int i, int j) {
        int result = i - j;
        return result;
    }

    @Override
    public int mul(int i, int j) {
        int result = i * j;
        return result;
    }

    @Override
    public int div(int i, int j) {
        int result = i / j;
        return result;
    }

}

// \src\com\atguigu\spring\aop\ArithmeticCalculatorLoggingImpl.java
package com.atguigu.spring.aop;

public class ArithmeticCalculatorLoggingImpl implements ArithmeticCalculator {

    @Override
    public int add(int i, int j) {
        System.out.println("The method add begins with [" + i + "," + j + "]");
        int result = i + j;
        System.out.println("The method add ends with " + result);
        return result;
    }

    @Override
    public int sub(int i, int j) {
        System.out.println("The method sub begins with [" + i + "," + j + "]");
        int result = i - j;
        System.out.println("The method sub ends with " + result);
        return result;
    }

    @Override
    public int mul(int i, int j) {
        System.out.println("The method mul begins with [" + i + "," + j + "]");
        int result = i * j;
        System.out.println("The method mul ends with " + result);
        return result;
    }

    @Override
    public int div(int i, int j) {
        System.out.println("The method div begins with [" + i + "," + j + "]");
        int result = i / j;
        System.out.println("The method div ends with " + result);
        return result;
    }

}

// \src\com\atguigu\spring\aop\ArithmeticCalculatorLoggingProxy.java
package com.atguigu.spring.aop;

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

public class ArithmeticCalculatorLoggingProxy {

    //要代理的对象
    private ArithmeticCalculator target;

    public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) {
        super();
        this.target = target;
    }

    //返回代理对象
    public ArithmeticCalculator getLoggingProxy(){
        ArithmeticCalculator proxy = null;

        ClassLoader loader = target.getClass().getClassLoader();
        Class [] interfaces = new Class[]{ArithmeticCalculator.class};
        InvocationHandler h = new InvocationHandler() {
            /**
             * proxy: 代理对象。 一般不使用该对象
             * method: 正在被调用的方法
             * args: 调用方法传入的参数
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                String methodName = method.getName();
                //打印日志
                System.out.println("[before] The method " + methodName + " begins with " + Arrays.asList(args));

                //调用目标方法
                Object result = null;

                try {
                    //前置通知
                    result = method.invoke(target, args);
                    //返回通知, 可以访问到方法的返回值
                } catch (NullPointerException e) {
                    e.printStackTrace();
                    //异常通知, 可以访问到方法出现的异常
                }

                //后置通知. 因为方法可以能会出异常, 所以访问不到方法的返回值

                //打印日志
                System.out.println("[after] The method ends with " + result);

                return result;
            }
        };

        /**
         * loader: 代理对象使用的类加载器。
         * interfaces: 指定代理对象的类型. 即代理代理对象中可以有哪些方法.
         * h: 当具体调用代理对象的方法时, 应该如何进行响应, 实际上就是调用 InvocationHandler 的 invoke 方法
         */
        proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);

        return proxy;
    }
}

// \src\com\atguigu\spring\aop\LoggingAspect.java
package com.atguigu.spring.aop;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * AOP 的 helloWorld
 * 1. 加入 jar 包
 * com.springsource.net.sf.cglib-2.2.0.jar
 * com.springsource.org.aopalliance-1.0.0.jar
 * com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
 * spring-aspects-4.0.0.RELEASE.jar
 *
 * 2. 在 Spring 的配置文件中加入 aop 的命名空间。
 *
 * 3. 基于注解的方式来使用 AOP
 * 3.1 在配置文件中配置自动扫描的包: <context:component-scan base-package="com.atguigu.spring.aop"></context:component-scan>
 * 3.2 加入使 AspjectJ 注解起作用的配置: <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
 * 为匹配的类自动生成动态代理对象.
 *
 * 4. 编写切面类:
 * 4.1 一个一般的 Java 类
 * 4.2 在其中添加要额外实现的功能.
 *
 * 5. 配置切面
 * 5.1 切面必须是 IOC 中的 bean: 实际添加了 @Component 注解
 * 5.2 声明是一个切面: 添加 @Aspect
 * 5.3 声明通知: 即额外加入功能对应的方法.
 * 5.3.1 前置通知: @Before("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(int, int))")
 * @Before 表示在目标方法执行之前执行 @Before 标记的方法的方法体.
 * @Before 里面的是切入点表达式:
 *
 * 6. 在通知中访问连接细节: 可以在通知方法中添加 JoinPoint 类型的参数, 从中可以访问到方法的签名和方法的参数.
 *
 * 7. @After 表示后置通知: 在方法执行之后执行的代码.
 */

//通过添加 @Aspect 注解声明一个 bean 是一个切面!
@Aspect
@Component
public class LoggingAspect {

    @Before("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(int, int))")
    public void beforeMethod(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        Object [] args = joinPoint.getArgs();

        System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));
    }

    @After("execution(* com.atguigu.spring.aop.*.*(..))")
    public void afterMethod(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("The method " + methodName + " ends");
    }

}

// \src\com\atguigu\spring\aop\Main.java
package com.atguigu.spring.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
//      ArithmeticCalculator arithmeticCalculator = new ArithmeticCalculatorImpl();
//
//      arithmeticCalculator =
//              new ArithmeticCalculatorLoggingProxy(arithmeticCalculator).getLoggingProxy();
//
//      int result = arithmeticCalculator.add(11, 12);
//      System.out.println("result:" + result);
//
//      result = arithmeticCalculator.div(21, 3);
//      System.out.println("result:" + result);

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-aop.xml");
        ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator");

        System.out.println(arithmeticCalculator.getClass().getName());

        int result = arithmeticCalculator.add(11, 12);
        System.out.println("result:" + result);

        result = arithmeticCalculator.div(21, 3);
        System.out.println("result:" + result);
    }

}

// \src\com\atguigu\spring\helloworld\HelloWorld.java
package com.atguigu.spring.helloworld;

public class HelloWorld {

    //字段
    private String user;

    public HelloWorld() {
        System.out.println("HelloWorld‘s constructor...");
    }

    //JavaBean 使用 setter 和 getter 来定义属性
    public void setUserName(String user) {
        System.out.println("setUserName:" + user);
        this.user = user;
    }

    public void hello(){
        System.out.println("Hello:" + user);
    }

    public void init(){
        System.out.println("init method...");
    }

    public void destroy(){
        System.out.println("destroy method...");
    }

}

// \src\com\atguigu\spring\helloworld\Main.java
package com.atguigu.spring.helloworld;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {

        //1. 创建 IOC 容器
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2. 从 IOC 容器中获取 bean 实例
        HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld");

        //3. 调用 bean 的方法
        helloWorld.hello();

        HelloWorld helloWorld2 = (HelloWorld) ctx.getBean("helloWorld");
        System.out.println(helloWorld == helloWorld2);

        //4. 关闭容器
        ctx.close();
    }

}

// \src\com\atguigu\spring\ref\Main.java
package com.atguigu.spring.ref;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {

        //1. 创建 IOC 容器
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-annotation.xml");

        UserAction userAction = (UserAction) ctx.getBean("userAction");
        userAction.execute();
    }

}

// \src\com\atguigu\spring\ref\UserAction.java
package com.atguigu.spring.ref;

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

@Controller
public class UserAction {

    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void execute(){
        System.out.println("execute...");
        userService.addNew();
    }

}

// \src\com\atguigu\spring\ref\UserDao.java
package com.atguigu.spring.ref;

import org.springframework.stereotype.Repository;

@Repository
public class UserDao {

    public void save(){
        System.out.println("UserDao‘s save...");
    }

}

// \src\com\atguigu\spring\ref\UserService.java
package com.atguigu.spring.ref;

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

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void addNew(){
        System.out.println("addNew...");
        userDao.save();
    }

}
时间: 2024-10-10 21:57:46

Spring 教程02的相关文章

[转载]AngularJS入门教程02:AngularJS模板

是时候给这些网页来点动态特性了——用AngularJS!我们这里为后面要加入的控制器添加了一个测试. 一个应用的代码架构有很多种.对于AngularJS应用,我们鼓励使用模型-视图-控制器(MVC)模式解耦代码和分离关注点.考虑到这一点,我们用AngularJS来为我们的应用添加一些模型.视图和控制器. 请重置工作目录: git checkout -f step-2 我们的应用现在有了一个包含三部手机的列表. 步骤1和步骤2之间最重要的不同在下面列出.,你可以到GitHub去看完整的差别. 视图

Angular系列----AngularJS入门教程02:静态模板(转载)

为了说明angularJS如何增强了标准HTML,我们先将创建一个静态HTML页面模板,然后把这个静态HTML页面模板转换成能动态显示的AngularJS模板. 在本步骤中,我们往HTML页面中添加两个手机的基本信息,用以下命令将工作目录重置到步骤1. git checkout -f step-1 请编辑app/index.html文件,将下面的代码添加到index.html文件中,然后运行该应用查看效果. app/index.html <ul> <li> <span>

Spring(02)重新认识 IoC

目录 Spring(02)重新认识 IoC 1. IoC 发展简介 2. IoC 主要实现策略 3. IoC 容器的职责 4. IoC 容器的实现 5. 传统 IoC 容器实现 6. 轻量级 IoC 容器 7. 依赖查找VS. 依赖注入 8. 构造器注入 VS. Setter 注入 9. 面试题精选 Spring(02)重新认识 IoC 1. IoC 发展简介 1983年,Richard E. Sweet 在<The Mesa Programming Environment>中提出 "

Spring教程:tutorialspoint-spring

来自turorialspoint的Maven教程(英文),官网:https://www.tutorialspoint.com/spring/index.htm 这个教程在国内已经被翻译成中文(不过是属于机器翻译),官网:http://wiki.jikexueyuan.com/project/spring/ 离线版本:链接:http://pan.baidu.com/s/1miJUM5i 密码:qj4q 总结: 1.本书比较容易上手,功能点达到中级,不会讲解升深入的难点,基本把Spring中级的功能

Spring 教程(四) Hello World 实例

Hello World 实例 让我们使用 Spring 框架开始实际的编程.在你开始使用 Spring 框架编写第一个例子之前,你必须确保已经正确地设置了 Spring 环境,正如在 Spring——环境设置 教程中如所说的.假设你有了解一些有关 Eclipse IDE 工作的知识. 因此,让我们继续编写一个简单的 Spring 应用程序,它将根据在 Spring Beans 配置文件中配置的信息输出 “Hello World!” 或其他信息. 第 1 步:创建 Java 项目 第一步是使用 E

Spring 教程(三) 环境设置

环境设置 本教程将指导你如何准备开发环境来使用 Spring 框架开始你的工作.本教程还将教你在安装 Spring 框架之前如何在你的机器上安装 JDK,Tomcat 和 Eclipse. 第 1 步:安装 Java 开发工具包(JDK) 你可以从 Oracle 的 Java 网站 Java SE Downloads 下载 SDK 的最新版本.你会在下载的文件中找到教你如何安装 JDK 的说明,按照给出的说明安装和配置 JDK 的设置.最后,设置 PATH 和 JAVA_HOME 环境变量,引入

Spring笔记02(3种加载配置文件的方式)

1.不使用Spring的实例: 01.Animal接口对应的代码: package cn.pb.dao; /** * 动物接口 */ public interface Animal { //吃饭 String eat(); //睡觉 void sleep(); } 02.Animal接口的实现类Dog对应的代码: package cn.pb.dao.impl; /** * animal的实现类 */ import cn.pb.dao.Animal; public class Dog implem

spring教程

Spring框架是Java EE开发中最流行的框架,已经成为JEE事实上的标准,全世界的开发人员都在使用Spring框架开发各种应用.随着Spring boot,Spring cloud新版本的不断推出,以及微服务的流行,Spring已经成为JEE开发"必修"项目. 本教程介绍spring框架的核心概念:DI.AOP等.本教程遵循二八原则(80%的场景只会用到20%的技术,也就是说大多数场景只会用少最常用的技术),我们只讲最重要最常用的部分,让你不走弯路,花最少时间学到最多. Spri

Spring Boot 02

YAMl配置文件: Spring Boot有两种配置文件 application.properties  和  application.yml  ,名称是固定不变的,yaml是一种比 xml  json 更适合的配置文件,不用关注属性的开闭. 1 语法格式: key:(空格)value       必须要有空格,以换行.空格的缩进来代表层级关系,并且大小写敏感 server: port: 8080 2 值的写法: 字面量:普通数值(数字,字符串,布尔) map.list. 对象: person: