例子中仅包含两种类:英雄类Hero和武器类Weapon。

  1. 演示DI:给Hero初始化Weapon
  2. 演示AOP:法师是一个英雄,当他发动攻击的时候需要念咒语,只有咒语正确才能施展魔法。通过定义一个切面来检验咒语的正确性(假设咒语必须要符合某种公共的标准。。。。。)

代码结构:

Spring容器的最小可用依赖

  1. Spring的核心是一个IOC容器,包含两个基础模块:context以及bean(必要)
  2. 添加AspectJ相关依赖用于支持AOP(必要
  3. 添加Log4j依赖方便输出(可选)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>sample</groupId>
<artifactId>spring</artifactId>
<version>1.0-SNAPSHOT</version> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- -source 1.5 中不支持 try-with-resources-->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- Use the latest version whenever possible. -->
<spring.version>5.1.3.RELEASE</spring.version>
<log4j.version>2.11.1</log4j.version>
<aspectj.version>1.9.2</aspectj.version>
</properties> <dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>

</dependencies>
</project>

用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">
<import resource="bean/weapons.xml"/>
<import resource="bean/heroes.xml"/>
</beans>

★子配置文件1:

<?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 id="mySword" class="sample.spring.iocbasis.weapon.Sword"/>
<bean id="myMagicBook" class="sample.spring.iocbasis.weapon.MagicBook"/> <aop:config>
<aop:aspect ref="myMagicBook">
<aop:pointcut id="mageAttack"
expression="execution(* sample.spring.iocbasis.hero.Mage.attack(String))" />
<aop:around pointcut-ref="mageAttack" method="magicLimit" />
</aop:aspect>
</aop:config>
</beans>

★子配置文件2,IDEA可能会报错说找不到引用,但其实是Ok的。注意不要重复import一个配置文件,这会导致重复定义bean或者切面:

<?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="iocWarrior" class="sample.spring.iocbasis.hero.Warrior">
<constructor-arg ref="mySword" />
</bean> <bean id="iocMage" class="sample.spring.iocbasis.hero.Mage">
<constructor-arg ref="myMagicBook" />
</bean>
</beans>

实例化容器&使用容器

★程序入口:

package sample.spring.iocbasis;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import sample.spring.iocbasis.hero.Hero;
import sample.spring.iocbasis.hero.Mage;
import sample.spring.iocbasis.hero.Warrior;
import sample.spring.iocbasis.weapon.MagicBook;
import sample.spring.iocbasis.weapon.Sword; public class MyTest {
public static void main(String[] args) {
System.out.println("===========手动调用setter方法注入=================");
Warrior warrior = new Warrior();
warrior.attack(null);
warrior.setWeapon(new Sword());
warrior.attack(null); System.out.println("===========手动调用构造器方法注入=================");
Warrior warrior2 = new Warrior(new Sword());
warrior2.attack(null); System.out.println("===========直接从IOC容器中获得事先组装好的对象=================");
ApplicationContext context = new ClassPathXmlApplicationContext("\\spring\\config.xml");
Warrior iocWarrior = context.getBean("iocWarrior", Warrior.class);
iocWarrior.attack(null); System.out.println("===========通过动态代理增强方法=================");
Hero iocMage = context.getBean("iocMage", Hero.class);
iocMage.attack("hello world.");
iocMage.attack("hlo worl."); System.out.println("===========绕过动态代理=================");
new Mage(new MagicBook()).attack("hlo worl.");
}
}
/*
===========手动调用setter方法注入=================
Warrior{no=1}用WoodenStick{}发起了一次攻击。
Warrior{no=1}用Sword{no=1}发起了一次攻击。
===========手动调用构造器方法注入=================
Warrior{no=2}用Sword{no=2}发起了一次攻击。
===========直接从IOC容器中获得事先组装好的对象=================
Warrior{no=3}用Sword{no=3}发起了一次攻击。
===========通过动态代理增强方法=================
Mage{no=1}试图发动一次魔法攻击,准备校验咒语【hello world.】正确性 ...
Mage{no=1}用MagicBook{no=1}发起了一次攻击
Mage{no=1}试图发动一次魔法攻击,准备校验咒语【hlo worl.】正确性 ...
Mage{no=1}的咒语念错了,魔法发动失败 ...
===========绕过动态代理=================
Mage{no=2}用MagicBook{no=2}发起了一次攻击
*/

唯一能看出“第三方依赖痕迹”的类:

package sample.spring.iocbasis.weapon;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint; public class MagicBook implements Weapon { private static final Logger LOGGER = LogManager.getLogger(); private static int count = 0; private int no = ++count; @Override
public void attack() { } public void magicLimit(ProceedingJoinPoint jp) {
try {
Object obj = jp.getThis();
String spell = String.valueOf(jp.getArgs()[0]);
LOGGER.info("{}试图发动一次魔法攻击,准备校验咒语【{}】正确性 ...", obj, spell);
if ("hello world.".equals(spell)) {
jp.proceed();
} else {
LOGGER.info("{}的咒语念错了,魔法发动失败 ...", obj);
}
} catch
(Throwable throwable) {
throwable.printStackTrace();
}
}
@Override
public String toString() {
return "MagicBook{" +
"no=" + no +
'}';
}
}

其它类:

package sample.spring.iocbasis.hero;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import sample.spring.iocbasis.weapon.Weapon;
import sample.spring.iocbasis.weapon.WoodenStick; public class Warrior implements Hero { private static final Logger LOGGER = LogManager.getLogger(); private static int count = 0; private int no = ++count; private Weapon weapon; public Warrior() {
weapon = new WoodenStick();
} public Warrior(Weapon weapon) {
this.weapon = weapon;
} public void setWeapon(Weapon weapon) {
this.weapon = weapon;
} @Override
public void attack(String sth) {
LOGGER.info("{}用{}发起了一次攻击。", this, weapon);
weapon.attack();
} @Override
public String toString() {
return "Warrior{" +
"no=" + no +
'}';
}
}

Warrior.java

package sample.spring.iocbasis.hero;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import sample.spring.iocbasis.weapon.Weapon; public class Mage implements Hero { private static final Logger LOGGER = LogManager.getLogger(); private static int count = 0; private int no = ++count; private Weapon weapon; public Mage(Weapon weapon) {
this.weapon = weapon;
} @Override
public void attack(String spell) {
LOGGER.info("{}用{}发起了一次攻击", this, weapon);
} @Override
public String toString() {
return "Mage{" +
"no=" + no +
'}';
}
}

Mage.java

package sample.spring.iocbasis.weapon;

public class Sword implements Weapon {

    private static int count = 0;

    private int no = ++count;

    @Override
public void attack() {
} @Override
public String toString() {
return "Sword{" +
"no=" + no +
'}';
}
}

Sword.java

package sample.spring.iocbasis.weapon;

public class WoodenStick implements Weapon {
@Override
public void attack() {
} @Override
public String toString() {
return "WoodenStick{}";
}
}

WoodenStick.java

package sample.spring.iocbasis.hero;

public interface Hero {

    void attack(String sth);
}

Hero.java

Spring笔记 #01# 一个小而生动的IOC例子代码的更多相关文章

  1. Spring笔记01(基础知识)

    1.基础知识 01.Spring:轻量级Java EE开源框架,它是由Rod Johnson为了解决企业应用程序开发的复杂性而创建. 02.目标:实现一个全方位的整合框架,实现“一站式”的企业应用开发 ...

  2. c++学习笔记---03---从一个小程序说起2

    从一个小程序说起2 要求:编写一个程序,要求用户输入一串整数和任意数目的空格,这些整数必须位于同一行中,但允许出现在该行中的任何位置.当用户按下键盘上的"Enter"键时,数据输入 ...

  3. c++学习笔记---02---从一个小程序说起

    从一个小程序说起 这一讲的主要目的是帮助大家在C语言的背景知识上与C++建立联系. 问题探索 问题:对一个整型数组求和. 要求:定义一个存储着 n 个元素的数组,要求用C语言完成这个任务. 赶紧的:大 ...

  4. Vue2.x源码学习笔记-从一个小例子查看vm实例生命周期

    学习任何一门框架,都不可能一股脑儿的从入口代码从上到下,把代码看完, 这样其实是很枯燥的,我想也很少有人这么干,或者这么干着干着可能干不下去了. 因为肯定很无聊. 我们先从一个最最简单的小例子,来查看 ...

  5. python笔记3----第一个小爬虫

    1.先看看要爬的网站有没有爬虫协议,可以看该网站有没有robots.txt,如豆瓣的: 2.requests模块:[requests是第三方,代码比python自带的urllib模块简单] 先加载re ...

  6. Spring笔记01

    spring 第一章 Spring模块规划图 核心架包 spring-beans-4.0.0.RELEASE. spring-core-4.0.0.RELEASE. spring-context-4. ...

  7. spring boot的一个小项目小型进销存系统

    项目所需的依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId&g ...

  8. 关于封装的一个小问题和TA的例子

    写个小例子吧 --  很多细节(如校验.判断等等)都略了 其实不是有意写成这样,而是很多朋友都这么写(当然里面也有点夸张的写法) 这么写其实也没什么不好,简单明了,不用动脑子,一看就很直白, 但是如果 ...

  9. Oracle学习笔记:一个简单的行转列例子

    一个简单的行列转换例子,原始数据. create table temp_cwh_student ( name ), subject ), score ) ) select * from temp_cw ...

随机推荐

  1. 一、Sql Server 基础培训《进度1-建库建数据表(实际操作)》

    知识点: 1.建数据库示例参考 --创建一个数据库名为‘dbtest’ create database dbtest go --打开数据库 dbtest use dbtest go 2.建表示例参考 ...

  2. cc攻击和ddos攻击

    DoS攻击.CC攻击的攻击方式和防御方法 DDoS介绍 DDoS是英文Distributed Denial of Service的缩写,意即“分布式拒绝服务”,那么什么又是拒绝服务(Denial of ...

  3. geotrellis使用(四十一)流水线技术

    前言 之前 GeoTrellis 为方便用户将数据(GeoTiff 等遥感影像)导入到 backend (包含 Accumulo.File.Hadoop 等格式)中,编写了一个 ETL 类,该类的输入 ...

  4. hive 元数据库表描述

    元数据库表描述 这一节描述hive元数据库中比较重要的一些表的作用,随着后续对hive的使用逐渐补充更多的内容. mysql元数据库hive中的表: 表名 作用 BUCKETING_COLS 存储bu ...

  5. export及export default的区别

    在JavaScript ES6中,export与export default均可用于导出常量.函数.文件.模块等,你可以在其它文件或模块中通过import+(常量 | 函数 | 文件 | 模块)名的方 ...

  6. 微信小程序开发笔记03

    今天基本实现了微信小程序主要功能,页面还没有进行优化,有些功能还需完善. 页面之间的信息转化部分还未实现.

  7. 20144306《网络对抗》MAL_恶意代码分析

    一.基础问题 1.如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些,用什么方法来监控? 使用Windows自带的schtasks指 ...

  8. 【摘】Fiddler工具使用介绍

    摘自:https://www.cnblogs.com/miantest/p/7289694.html Fiddler基础知识 Fiddler是强大的抓包工具,它的原理是以web代理服务器的形式进行工作 ...

  9. Mac 启动或者禁用翻盖自动开关机

    从 2016 新款 MacBook Pro 起,预设打开笔电上盖或连接电源供应器时,电脑就会自动开机而且开机时没有启动声,本文教你如何将这些东西调整回原本的样子. 以下指令都是通过「应用程序」→「终端 ...

  10. 记一次mysql事故---纪念逝去的一上午

    虚拟机关机后第二天mysql起不来,回想一下我关机前和关机后的操作发现:关机前没关闭mysqld服务就直接init 0了,关机后将虚拟机内存由1G降到724M.笔者保证再也做过别的骚操作了. -- : ...