现在我要出售一个比较牛逼的商品
它到底有多牛逼?
package com.lijinquan.spring;
/**
* Created by lijinquan on 2016/9/3.
*/
public class Item {
private String imName;
private Double imLenght;
private Double imWidth;
private Double imHeight;
public void show(){
System.out.println("没有一个亿不卖!");
}
public String getImName() {
return imName;
}
public void setImName(String imName) {
this.imName = imName;
}
public Double getImLenght() {
return imLenght;
}
public void setImLenght(Double imLenght) {
this.imLenght = imLenght;
}
public Double getImWidth() {
return imWidth;
}
public void setImWidth(Double imWidth) {
this.imWidth = imWidth;
}
public Double getImHeight() {
return imHeight;
}
public void setImHeight(Double imHeight) {
this.imHeight = imHeight;
}
}
仅需隔壁老王的一个小目标
你都买不到
为何如此牛逼?
因为你需要购买入场券,买了之后你还要说good
/**
* Created by lijinquan on 2016/9/3.
*/
public class ItemProxy {
public void need(){
System.out.println("你需要入场券!");
}
public void after(){
System.out.println("good");
}
}
这到底是怎么回事?
是这样的,我创建了一个商品类Item,一个用来做切面的的类ItemProxy ,下面我着重拿他们两个来说事儿
用Idea创建一个java maven项目,文件结构如下
既然是讲spring的,那spring依赖你得有
好的
端上
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
放入pom.xml文件中
导入依赖
此时还需要一些配置,将我哪每一个亿不卖的商品交给spring管理
怎么来配置呢?
在上面项目中的resources的app.xml文件中加入如下配置信息
<bean id="item" class="com.lijinquan.spring.Item"></bean>
既然是讲原理性的东西,我就说说这句话原理
id唯一的随便起,class就是需要配置给spring管理的类(Item),他的id我这命名item
完整版是这样的
<?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 https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="item" class="com.lijinquan.spring.Item"></bean>
</beans>
讲完上面的搭建和基本配置
来写几行代码热热身
/**
* Created by lijinquan on 2016/9/3.
*/
public class Main {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("app.xml");
Item item =(Item) context.getBean("item");
item.show();
}
}
在main方法中的这句
ApplicationContext context=new ClassPathXmlApplicationContext("app.xml");
意思是说从classpath(src)路径下找到app.xml文件
这里可以理解context为一个大工厂,他将app.xml里面的配置都读出来了
context.getBean("item");通过id获得一个对象,这个对象是谁,就是对应这个id的app配置文件里面class指的类,也就是Item这个类
spring自动帮我们生成这个对象放入了容器帮我们管理,这个就叫IOC :Inversion of Control,缩写为IoC
既然得到了item对象我们调用他的方法试试看
item.show();
运行结果
接着我需要继续加入这个商品一些拦截,没有入场券你就不能买
假如这个商品需要加入这种拦截处理,以后我再加入其他类型的商品呢,我没有10个亿不卖的呢
是不是需要每个业务类/方法都要加相应的拦截?不需要,再这里引入切面概念AoP :AOP为Aspect Oriented Programming的缩写
只需要引入相应的切面依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
再在app.xml文件中加入一句配置
<bean id="itemProxy" class="com.lijinquan.spring.ItemProxy"></bean>
把这个切面要切入的方法的类代码也交给spring管理
再配置一个切面配置
<aop:config>
<aop:aspect id="ne" ref="itemProxy">
<aop:pointcut id="todo" expression="execution(void com.lijinquan.spring.Item.show())"/>
<aop:before method="need" pointcut-ref="todo"/>
<aop:after method="after" pointcut-ref="todo"/>
</aop:aspect>
</aop:config>
好,完整的app.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="item" class="com.lijinquan.spring.Item"></bean>
<bean id="itemProxy" class="com.lijinquan.spring.ItemProxy"></bean>
<aop:config>
<aop:aspect id="ne" ref="itemProxy">
<aop:pointcut id="todo" expression="execution(void com.lijinquan.spring.Item.show())"/>
<aop:before method="need" pointcut-ref="todo"/>
<aop:after method="after" pointcut-ref="todo"/>
</aop:aspect>
</aop:config>
</beans>
配置都是固定写法,格式固定
里面的配置是什么意思呢?看下图
我这个截图软件犀利把,我把两个文件的截图合合成一张了,结合箭头我讲讲这个配置吧
<aop:aspect id="ne" ref="itemProxy">
这句id也是随便起,ref指的就是ItemProxy这个类配置的Id,也就是指这个类,这个切面切谁进去?就是切这个类。
怎么切?
<aop:pointcut id="todo" expression="execution(void com.lijinquan.spring.Item.show())"/>
id也是任意唯一的起名,execution执行com.lijinquan.spring.Item.show()这个类的show方法的时候
如果Item不止show()一个方法呢?用com.lijinquan.spring.Item.*,com.lijinquan.spring.*.*都行
<aop:before method="need" pointcut-ref="todo"/>
这行配置指的是再运行Item的show()之前,先运行切面切入的need(), 就是ItemProxy中的need()业务方法,功能是需要入场券
<aop:after method="after" pointcut-ref="todo"/>
这行配置指的是再运行Item的show()之后,再运行切面切入的after(),就是ItemProxy中的after()业务方法,功能是good
上面我用不同颜色分开介绍这aop的配置,更加好区分
配置讲完了,运行下刚刚的main方法,看看效果
没有一个亿不卖以前,执行了need(), 后,执行了after()
以上,实现了一个简单的IOC和AOP项目
但是是不是觉得那个配置很繁琐呢?
还有另外一种方式
需要改造一下这个项目才能继续讲下去,改造中...
把项目的三个文件Item,ItemProxy ,Main放入v1文件夹
再复制一份放入v2文件夹
再在resources文件夹下创建一个app-anot.xml
结果项目结构是这样的
我们配置下app-anot.xml
加入一句
<aop:aspectj-autoproxy/>
意思是自动将aop:aspectj配置进去
再将
<bean id="item" class="com.lijinquan.spring.v2.Item"></bean> <bean id="itemProxy" class="com.lijinquan.spring.v2.ItemProxy"></bean>
这两个类交给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" 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 https://www.springframework.org/schema/aop/spring-aop.xsd"> <aop:aspectj-autoproxy/> <bean id="item" class="com.lijinquan.spring.v2.Item"></bean> <bean id="itemProxy" class="com.lijinquan.spring.v2.ItemProxy"></bean> </beans>
接着再改造一下ItemProxy
把
@Aspect 放到ItemProxy类的头上
再
@Before("execution(void com.lijinquan.spring.v2.Item.show())")
@After("execution(void com.lijinquan.spring.v2.Item.show())")
分别放入,具体看完整版吧
/** * Created by lijinquan on 2016/9/3. */ @Aspect public class ItemProxy { @Before("execution(void com.lijinquan.spring.v2.Item.show())") public void need(){ System.out.println("你需要入场券!"); } @After("execution(void com.lijinquan.spring.v2.Item.show())") public void after(){ System.out.println("good"); } }
这么来写跟当时app.xml里面的配置信息我就不一一解释了,但是效果和v1一样的,且看运行结果
这种方法要比第一种好写一些,但是特别注意再大项目里面,切面的代码和具体的要被切入的分开放,也不能分在太零散得包中,要考虑方便维护的问题
各位,我先洗澡去了,为了整理以前的东西,上班好困,下班回来也困,洗完澡还要干别的,码字不易