Spring笔记 #01# 一个小而生动的IOC例子代码
例子中仅包含两种类:英雄类Hero和武器类Weapon。
- 演示DI:给Hero初始化Weapon
- 演示AOP:法师是一个英雄,当他发动攻击的时候需要念咒语,只有咒语正确才能施展魔法。通过定义一个切面来检验咒语的正确性(假设咒语必须要符合某种公共的标准。。。。。)
代码结构:
Spring容器的最小可用依赖
- Spring的核心是一个IOC容器,包含两个基础模块:context以及bean(必要)
- 添加AspectJ相关依赖用于支持AOP(必要)
- 添加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例子代码的更多相关文章
- Spring笔记01(基础知识)
1.基础知识 01.Spring:轻量级Java EE开源框架,它是由Rod Johnson为了解决企业应用程序开发的复杂性而创建. 02.目标:实现一个全方位的整合框架,实现“一站式”的企业应用开发 ...
- c++学习笔记---03---从一个小程序说起2
从一个小程序说起2 要求:编写一个程序,要求用户输入一串整数和任意数目的空格,这些整数必须位于同一行中,但允许出现在该行中的任何位置.当用户按下键盘上的"Enter"键时,数据输入 ...
- c++学习笔记---02---从一个小程序说起
从一个小程序说起 这一讲的主要目的是帮助大家在C语言的背景知识上与C++建立联系. 问题探索 问题:对一个整型数组求和. 要求:定义一个存储着 n 个元素的数组,要求用C语言完成这个任务. 赶紧的:大 ...
- Vue2.x源码学习笔记-从一个小例子查看vm实例生命周期
学习任何一门框架,都不可能一股脑儿的从入口代码从上到下,把代码看完, 这样其实是很枯燥的,我想也很少有人这么干,或者这么干着干着可能干不下去了. 因为肯定很无聊. 我们先从一个最最简单的小例子,来查看 ...
- python笔记3----第一个小爬虫
1.先看看要爬的网站有没有爬虫协议,可以看该网站有没有robots.txt,如豆瓣的: 2.requests模块:[requests是第三方,代码比python自带的urllib模块简单] 先加载re ...
- Spring笔记01
spring 第一章 Spring模块规划图 核心架包 spring-beans-4.0.0.RELEASE. spring-core-4.0.0.RELEASE. spring-context-4. ...
- spring boot的一个小项目小型进销存系统
项目所需的依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId&g ...
- 关于封装的一个小问题和TA的例子
写个小例子吧 -- 很多细节(如校验.判断等等)都略了 其实不是有意写成这样,而是很多朋友都这么写(当然里面也有点夸张的写法) 这么写其实也没什么不好,简单明了,不用动脑子,一看就很直白, 但是如果 ...
- Oracle学习笔记:一个简单的行转列例子
一个简单的行列转换例子,原始数据. create table temp_cwh_student ( name ), subject ), score ) ) select * from temp_cw ...
随机推荐
- Inside The C++ Object Model(二)
============================================================================2-0. 关键字explicit被引入C++,提 ...
- Android Adb命令查看包名信息
Android O 8.1.0 data/system/packages.listdata/system/packages.xmldata/system/package-usage.listdata/ ...
- vue重要项目的参考
https://github.com/PanJiaChen/vue-element-admin vue项目参考 重点 https://github.com/opendigg/awesome-gith ...
- 3.nodejs(三) 常用API
1.querystring querystring: --- > qs npm i qs ==> qs:parse/stringify第三方插件,只有一个参数 JSON.parse 字符 ...
- yarn-RM-check-by-curl
#!bin/bash SELF_DIR="$( cd "$( dirname "$0" )" && pwd )" #grep ...
- HTML01
1.什么是HTML?(Hyper Text Markup Language:超文本标记语言) 超文本:功能比普通文本更加强大 标记语言:使用一组标签对内容进行描述的一门语言(它不是编程语言) 2.为什 ...
- Python网络编程-Socket简单通信(及python实现远程文件发送)
学习python中使用python进行网络编程,编写简单的客户端和服务器端进行通信,大部分内容来源于网络教程,这里进行总结供以后查阅. 先介绍下TCP的三次握手: 1,简单的发送消息: 服务器端: i ...
- LeetCode 237 Delete Node in a Linked List 解题报告
题目要求 Write a function to delete a node (except the tail) in a singly linked list, given only access ...
- python基础(15)-socket网络编程&socketserver
socket 参数及方法说明 初始化参数 sk = socket.socket(参数1,参数2,参数3) 参数1:地址簇 socket.AF_INET IPv4(默认) socket.AF_INET6 ...
- IIS相关
使用aspnet_regiis.exe重新注册.NET Framework 重新安装IIS以后,需要用aspnet_regiis.exe来注册.NET Framework, 如下: C:\WINDOW ...