例子中仅包含两种类:英雄类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. 【中间件安全】Jboss安全加固规范

    1. 适用情况 适用于使用Jboss进行部署的Web网站. 适用版本:5.x版本的Jboss服务器 2. 技能要求 熟悉Jboss安装配置,能够Jboss进行部署,并能针对站点使用Jboss进行安全加 ...

  2. Git忽略已经被版本控制的文件(添加.gitignore不会起作用)

    说明:已经被维护起来的文件(需要被远程仓库控制),即使加入.gitignore也会无济于事. .gitignore只对那些只存在在本地,而不在远程仓库的文件起作用.(untraked file). 操 ...

  3. 如何使用Vue-cli搭建和运行vue项目

    此文章  主要参考:https://jingyan.baidu.com/article/5225f26bbb430fe6fa0908ce.html 在vue init webpack my-proje ...

  4. gym 101858

    我这个傻逼被治了一下午. 大好的橘势,两个小时6T,去看L,哇傻逼题.然后我跑的最短路T到自闭 最后十几分钟去想了下A,一直在想如何表示状态..就是想不到二进制搞一下... 然后游戏结束了..以后我就 ...

  5. Linux上配置http上网代理

    有些局域网环境上网需要使用代理上网,图形界面的很好解决就设置一下浏览器的代理就好了,但是Linux纯命令行的界面就需要手动配置了. 如果要全局用户使用应用于所有的Shell,就需要修改 /etc/pr ...

  6. 二、JavaScript基础(1)

    1.JavaScript 基于对象和事件驱动的脚步语言,主要应用在客户端 特点:交互性(信息的动态交互).安全性(不可直接访问本地硬盘).跨平台性(只要可以解析js的浏览器 都可以执行,与平台无关) ...

  7. PHP指定时间戳/日期加一天,一年,一周,一月

    PHP指定时间戳加上1天,1周,1月,一年其实是不需要用上什么函数的!指定时间戳本身就是数字整型,我们只需要再计算1天,1周它的秒数相加即可! 博主搜索php指定时间戳加一天一年,结果许多的文章给出来 ...

  8. HTML、CSS知识点,面试开发都会需要--No.1 HTML

    No.1   HTML 1.网页结构 网页结构一般都包含文档声明DOCTYPE,并且在head中的meta应该包含编码格式.关键字.网页描述信息.简单格式如下: <!DOCTYPE html&g ...

  9. Rob Pike

    罗布·派克_百度百科 https://baike.baidu.com/item/罗布·派克   1. 你无法断定程序会在什么地方耗费运行时间.瓶颈经常出现在想不到的地方,所以别急于胡乱找个地方改代码, ...

  10. DEDE暴力破解后台登录页面

    DEDE暴力破解后台登录页面 #!/usr/bin/env python '''/* * author = Mochazz * team = 红日安全团队 * env = pyton3 * */ '' ...