Spring面向切面编程--不修改类的情况下,为类新增方法。

通过注解引入新功能

之前的文章(Spring面向切面编程 AOP,实现AOP注解和XML配置的小例子)实现了在不修改类的情况下,为方法新增功能。这篇文章将讲述,在不修改类的情况下,如何为类新增方法。
我们先来看一个实现此功能的小例子,然后再来解析它是如何实现此功能的。

package aop;

public interface IPerformance {
	public void perform();
}
package aop;

import org.springframework.stereotype.Component;

@Component
public class Performance implements IPerformance{
	@Override
	public void perform() {
		System.out.println("表演开始");
	}
}


package aop;

public interface IShow {
	public void show();
}

package aop;

import org.springframework.stereotype.Component;

@Component
public class Show implements IShow{
	@Override
	public void show() {
		System.out.println("演出结束");
	}
}

package aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class DeclareParent {
	@DeclareParents(value = "aop.IPerformance+",defaultImpl=Show.class)
	public IShow ishow;
}

pom.xml 个人做项目的pom.xml文件,如有不需要这么多的,可自行删除。

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.liangyu.aop</groupId>
  <artifactId>aopDemo</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>aopDemo Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
  	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-aop</artifactId>
	    <version>5.1.5.RELEASE</version>
	</dependency>
	
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-aspects</artifactId>
	    <version>5.1.5.RELEASE</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
	<dependency>
	    <groupId>org.aspectj</groupId>
	    <artifactId>aspectjweaver</artifactId>
	    <version>1.9.2</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
	<dependency>
	    <groupId>org.aspectj</groupId>
	    <artifactId>aspectjrt</artifactId>
	    <version>1.9.2</version>
	</dependency>
	
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-beans</artifactId>
	    <version>5.1.5.RELEASE</version>
	</dependency>
	
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-context</artifactId>
	    <version>5.1.5.RELEASE</version>
	    <type>pom</type>
	</dependency>
	
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-core</artifactId>
	    <version>5.1.5.RELEASE</version>
	    <type>pom</type>
	</dependency>
	
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-expression</artifactId>
	    <version>5.1.5.RELEASE</version>
	    <type>pom</type>
	</dependency>
	
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-tx</artifactId>
	    <version>5.1.5.RELEASE</version>
	    <type>pom</type>
	</dependency>
	
	
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-web</artifactId>
	    <version>5.1.5.RELEASE</version>
	    <type>pom</type>
	</dependency>
	
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-webmvc</artifactId>
	    <version>5.1.5.RELEASE</version>
	    <type>pom</type>
	</dependency>
	
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-test</artifactId>
	    <version>5.1.4.RELEASE</version>
	    <type>pom</type>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
	<dependency>
	    <groupId>org.apache.commons</groupId>
	    <artifactId>commons-collections4</artifactId>
	    <version>4.3</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
	<dependency>
	    <groupId>commons-logging</groupId>
	    <artifactId>commons-logging</artifactId>
	    <version>1.2</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/cglib/cglib-nodep -->
	<dependency>
	    <groupId>cglib</groupId>
	    <artifactId>cglib-nodep</artifactId>
	    <version>3.2.10</version>
	</dependency>

	<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
	<dependency>
	    <groupId>aopalliance</groupId>
	    <artifactId>aopalliance</artifactId>
	    <version>1.0</version>
	</dependency>				
	
	<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
	<dependency>
	    <groupId>org.apache.commons</groupId>
	    <artifactId>commons-dbcp2</artifactId>
	    <version>2.6.0</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/junit/junit -->
	<dependency>
	    <groupId>junit</groupId>
	    <artifactId>junit</artifactId>
	    <version>4.12</version>
	    <scope>test</scope>
	</dependency>

  </dependencies>
  <build>
    <finalName>aopDemo</finalName>
  </build>
</project>

package aop;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@ComponentScan
@EnableAspectJAutoProxy
@Configuration
public class AOPConfig {

}
package aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

public class AopTest {	
	public static void main(String[] args) {
	     ApplicationContext ac = new AnnotationConfigApplicationContext("aop");
	     IPerformance perfomance = (IPerformance) ac.getBean("performance");
	     perfomance.perform();
	     IShow show = (IShow)perfomance;
	     show.show();
	}
}

运行结果如下:

表演开始
演出结束

可以看出已经实现来为IPerformance这个接口新增来一个show方法。

那么实现此功能引入了一个新的注解:@DeclareParents
@DeclareParents注解由三部分组成:

  • value属性指定了哪种类型的bean要引入该接口。
  • defaultImpl属性指定了为引入功能提供实现的类。
  • @DeclareParents注解所标注的属性指明了要引入的接口。

为了更好了理解上面这段话,把此实现类移动至下方供参考理解。

package aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class DeclareParent {
	@DeclareParents(value = "aop.IPerformance+",defaultImpl=Show.class)
	public IShow ishow;
}

注意:

该功能实现,只能使用在接口实现的方法,如果此方法没有实现接口,那么注解无效。例如Performance不实现任何接口,只是一个普通的类。同样,Show也不实现任何接口,也是一个普通的类,那么这种方式就会报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值