Spring(eclipse)简要笔记

目录

1.spring核心容器

1.2 ApplicationContext

 1.2.2 通过FileSystemXmlApplicationContext创建

2.XML的配置信息

3.spring的依赖注入(DI)

4.代理

5.AOP


1.spring核心容器

1.1 BeanFactory

其主要是一个管理Bean的工厂,主要负责初始化各种Bean,并调用他们的生命周期方法,语法如下:

//1.加载bean工厂
 BeanFactory beanfactory=new ClassPathXmlApplicationContext("app*.xml");

1.2 ApplicationContext

ApplicationContext是BeanFactory的子接口,也被称为应用上下文,是另一种常用的Spring的核心容器。它不仅包含了BeanFactory的所有功能,还添加了对国际化、资源访问、事件传播等方面的支持。语法如下:

1.2.1 通过ClassPathXmlApplicationContext创建(常用)

//1.加载bean工厂
 ApplicationContext applicationcontext=new ClassPathXmlApplicationContext("app1.xml");

 1.2.2 通过FileSystemXmlApplicationContext创建

FileSystemXmlApplicationContext会从指定的文件系统路径(绝对路径)区寻找指定的XML配置文件,找到并装载完成ApplicationContext的实列化工作,其灵活性较差,语法如下:

//1.加载bean工厂
 ApplicationContext applicationcontext=new FileSystemXmlApplicationContext(String configLocation);

2.XML的配置信息

以下示例显示了基于 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">
 ​
     <bean id="..." class="...">  (1) (2)
         
     </bean>
         
     <bean id="..." class="...">
         
     </bean>
 ​
 </beans>
  • (1) id属性是标识单个 bean 定义的字符串。

  • (2) class属性定义 bean 的类型并使用完全限定的类名。

id属性的值是指协作对象。在此示例中未显示用于引用协作对象的 XML。

3.spring的依赖注入(DI)

1.依赖注入:

IOC的作用:降低程序之间的耦合(依赖关系)

概念:依赖关系的管理交给spring维护,在当前类需要用到其他类的对象,由spring为我们提供,只需在配置文件中说明关系的维护;

2.能够注入的数据有三类:

1) 基本类型和string

2) 其他bean类型(在配置文件中或者注解配置过的bean)

3)复杂集合类型

3.两种注入方式

1)使用构造函数

1.先建立一个user类

public class user {
     private String username;
     private int password;
     private List<String> list;
     /*
      * 1.使用构造注入
      *  1.1提供带所有参数的有参构造方法
      */
     public user(String username, int password, List<String> list) {
         super();
         this.username = username;
         this.password = password;
         this.list = list;
     }
 @Override
     public String toString() {
         return "user [username=" + username + ", password=" + password + ", list=" + list + "]";
     }
 }

2.配置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-4.3.xsd">
     <!--使用构造注入的方式  -->
 <bean id="user1" class="com.ds.spring.user">
 <constructor-arg index="0" value="tom"/>
 <constructor-arg index="1" value="123456"/>
 <constructor-arg index="2">
 <list>
 <value>"constructorvalue1"</value>
 <value>"constructorvalue2"</value>
 </list>
 </constructor-arg>
 </bean>
 </beans>

3.运行输出

 @Test
     public void testem() {
         //1.加载bean工厂
         ApplicationContext beanfactory=new ClassPathXmlApplicationContext("app5.xml");
         //2.获取bean
         user u1=(user) beanfactory.getBean("user1");
         System.out.println(u1);
     }

2)set方法注入(常用)

设值注入是IoC容器使用成员变量的setter方法来注入被依赖对象。需满足两点:

(1)Bean类必须提供一个默认的无参构造方法。

(2)Bean类必须为需要注入的属性提供对应的setter方法。

1.先建一个user类

 
package com.ds.spring;
 ​
 import java.util.List;
 ​
 public class user {
     private String username;
     private int password;
     private List<String> list;
         /*
      * 2.使用设置注入 
      * 2.1提供默认的空参构造方法
      *  2.2为所有属性提供setter方法
      */
     public user() {
         super();
         // TODO Auto-generated constructor stub
     }
     public String getUsername() {
         return username;
     }
     public void setUsername(String username) {
         this.username = username;
     }
     public int getPassword() {
         return password;
     }
     public void setPassword(int password) {
         this.password = password;
     }
     public List<String> getList() {
         return list;
     }
     public void setList(List<String> list) {
         this.list = list;
     }
     @Override
     public String toString() {
         return "user [username=" + username + ", password=" + password + ", list=" + list + "]";
     }
 }
 ​

2.进行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-4.3.xsd">
 <!--使用设置注入  -->
 <bean id="user2" class="com.ds.spring.user">
 <property name="username" value="jack"/>
 <property name="password" value="654321"/>
 <property name="list">
 <list>
 <value>"setlistvalue1"</value>
 <value>"setlistvalue2"</value>
 </list>
 </property>
 </bean>
 </beans>

3.运行

 
public class test {
         @Test
     public void teste() {
         //1.加载bean工厂
         ApplicationContext beanfactory=new ClassPathXmlApplicationContext("app5.xml");
         //2.获取bean
         user u2=(user)beanfactory.getBean("user2");
         System.out.println(u2);
     }
     }

4.基于Annotation的装配

1)Spring中常用注解如下

  • @Commponent相当于new了个对象,也就是相当于<bean id=""/>中id的值,(不写括号里的名字的话默认类名的小写)

    img

  • @Repository功能与Commponent相同,但是其常用于数据访问层(DAO层)

  • @Service功能与Commponent相同,其常用于业务层(Service层)

  • @Controller功能与Commponent相同,其常用于控制层

  • @Autowired,该注解默认使用按类型自动装配Bean的方式。 使用该注解完成属性注入时,类中无需setter。当然,若属性有setter,则也可将其加到setter上。

    img

    img

  • @Qualifier的value属性用于指定要匹配的Bean的id值。同样类中无需setter,也可加到setter上。@Autowired与@Qualifier相当于@Resource(name=" ")

    img

  • @Scope,其value属性用于指定作用域。默认为singleton

    img

  • @Value,该注解的value属性用于指定要注入的值。

    img

  • @Resource是java自带的注解

@Resource注解既可以按名称匹配Bean,也可以按类型匹配Bean。使用该注解,要求JDK必须是6及以上版本。 (1)按类型注入域属性 @Resource注解若不带任何参数,看 Spring 容器中的 bean 中的 id 与@ Resource 要注解的那个变量属性名是否相 同,如相同,匹配成功;如不同 看 spring 容器中 bean 的 id 对应的类型是否与@ Resource 要注解的那个变量属性对应的类型是否相等,若相等,匹配成功,若不相等,匹配失败。

(先比较名字cat1和cat发现不同,然后就比较类名Cat和Cat发现相同,匹配成功)

2)按名称注入域属性 @Resource注解指定其name属性,则name的值即为按照名称进行匹配的Bean的id。

img

如下一个例子:

1.建立一个Cat类

package com.hkd.zhujie;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("cat1")//指定id为cat1
public class Cat {
	@Value("波斯猫")
	String name;
	public void shoutc() {
		System.out.println(name+"喵喵喵!");
	}
}

2.建立一个Dog类

package com.hkd.zhujie;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component//默认id为dog
public class Dog {
	@Value("金毛")
	String name;
public void shoutd() {
	System.out.println(name+"汪汪汪!");
}
}

3.建立Animal类,并引入Cat和Dog‘类

package com.hkd.zhujie;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Animal {
	//@Autowired//默认按类名进行找
	@Resource//默认先根据id和名字找,再根据类名找
	Dog dog;
//	@Autowired
//	@Qualifier("cat1")//按id名进行找
	@Resource(name="dog")//按id名找
	Cat cat;
	public Dog getDog() {
		return dog;
	}
	public void setDog(Dog dog) {
		this.dog = dog;
	}
	public Cat getCat() {
		return cat;
	}
	public void setCat(Cat cat) {
		this.cat = cat;
	}
	public void shouta() {
		dog.shoutd();
		cat.shoutc();
	}
	

}

4.扫描包(app6.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:context="http://www.springframework.org/schema/context"                     
	   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-4.3.xsd
	                       http://www.springframework.org/schema/context
	                    http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!--扫描包  -->
	                    <!--使用context命名空间,在配置文件中开启相应的注解处理器  -->
	                    <context:component-scan base-package="com.hkd.zhujie">
	                    </context:component-scan>
</beans>

5.测试

package com.hkd.zhujie;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {
public static void main(String[] args) {
	ApplicationContext app=new ClassPathXmlApplicationContext("app6.xml");
	Animal a=(Animal)app.getBean("animal");
	a.shouta();
}
}

5.使用JavaConfig配置

1)其完全不使用Spring的XML进行配置,全部交给Java来做,JavaConfig是Spring的一个子项目,在Spring4后,它成了一个核心功能。

1.建一个user类

package com.ds.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
public class user {
@Value("李白")
String name;

public String getName() {
	return name;
}

public void setName(String name) {
	this.name = name;
}

@Override
public String toString() {
	return "user [name=" + name + "]";
}

}

2.再建一个config类来配置

package com.ds.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration//代表的是一个配置类,相当于XML文件
public class config {
@Bean//这个方法的名字,相当于bean标签中的id属性
//返回值相当于bean标签的class属性
public user getuser() {
	return new user();
}
}

3.运行

package com.ds.config;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class test {
public static void main(String[] args) {
ApplicationContext app=new AnnotationConfigApplicationContext(config.class);
user u=(user)app.getBean("getuser");//方法名
System.out.println(u.getName());
}
}

4.代理

1)其含义就是通过第三方来代理我们的工作,用如下例子来说明

1.先写一个接口userservice

package com.fbw.agent;

public interface userservice {
	void add();
	void delete();
	void update();
	void quary();

}

2.userserviceimp实现这个接口

package com.fbw.agent;


//不能改源代码,创一个代理类
public class userserviceimp implements userservice {

	public void add() {
		// TODO Auto-generated method stub
        //System.out.println("使用了add方法");一般会这样写,但这样会比较臃肿,而且修改了源码,为了避免这些所以引出了代理
System.out.println("add a user");
	}

	public void delete() {
		// TODO Auto-generated method stub
        //System.out.println("使用了delete方法");
System.out.println("delete a user");
	}

	public void update() {
		// TODO Auto-generated method stub
        //System.out.println("使用了update方法");
System.out.println("update a user");
	}

	public void quary() {
		// TODO Auto-generated method stub
        //System.out.println("使用了quary方法");
System.out.println("quary a user");
	}

}

正常的话直接new对象就可以调用方法了,但现在有一个在每个方法上都加上“使用了...方法“的输出,而且是在不改变源码(修改源码是大忌)的条件下的需求,此时就要引入代理,代理可分为静态代理和动态代理:

1)静态代理

3.接上面的例子,创建一个名为userserviceagent的代理类来处理需求

package com.fbw.agent;


//代理类
public class userserviceagent implements userservice {
	userserviceimp usp;
	public void setUsp(userserviceimp usp) {
		this.usp = usp;
	}
    
    //引入需求
	public void log(String msg) {
	System.out.println("使用了"+msg+"方法");
}
	@Override
	public void add() {
		// TODO Auto-generated method stub
		log("add");
		usp.add();
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
log("delete");
usp.delete();
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
log("update");
usp.update();
	}

	@Override
	public void quary() {
		// TODO Auto-generated method stub
		log("quary");
		usp.quary();

	}

}

此时加入的需求就直接引用到了代理类里,源码也不必修改

4.测试

package com.fbw.agent;

public class test {
	public static void main(String[] args) {
		//要代理的类,真实角色
		userserviceimp usi=new userserviceimp();
		//代理类
		userserviceagent usa=new userserviceagent();
		//设置要代理的类
		usa.setUsp(usi);
		//调用方法
		usa.add();
		
	}
}

2)动态代理

有静态代理可以看出,其虽然实现了需求,但是其比较繁琐每次需要完成需求都要建立一个代理类,所以就引入了动态代理,动态代理是在反射的基础上完成的。

3.接上面的例子我们可以创建一个动态的代理万能类其需要实现InvocationHandler接口,如下(类名为ProxyInvocationHandler)

package com.fbw.agent;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import jdk.nashorn.internal.runtime.linker.InvokeByName;


//动态的工具类,自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
	//被代理的接口
private Object target;


public void setTarget(Object target) {
	this.target = target;
}

//生成得到代理类
public Object getproxy() {
		/*
		 * newProxyInstance,方法有三个参数:
		 * 
		 * loader: 用哪个类加载器去加载代理对象
		 * 
		 * interfaces:动态代理类需要实现的接口
		 * 
		 * h:动态代理方法在执行时,会调用h里面的invoke方法去执行
		 * 
		 * 其返回的是代理类
		 */
	return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(), this);
}
	
	
	//处理代理实例,并返回结果
	@Override
	public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
		// TODO Auto-generated method stub
		/*
		 * invoke三个参数:

		arg0:就是代理对象,newProxyInstance方法的返回对象
		
		arg1:调用的方法

		arg2: 方法中的参数
		
		method.invoke(Object obj,Object args[])的作用就是调用method类代表的方法,
		其中obj是接口名,args调用的obj中的方法的,也就是说其返回的是obj接口中的args方法
		*/
		//通过arg1.getName()来获取调用的方法名
		log(arg1.getName());
		Object result=arg1.invoke(target, arg2);
		return result;
	}
	public void log(String msg) {
		System.out.println("执行了"+msg+"方法");
	}

}
  • target:代表的是要被代理的接口

  • setTarget(Object target):为了使将要生成的代理类也实现接口

  • getproxy():其return的是要代理的类,其目的是为了的得到要代理的类,即userserviceimp类

  • newProxyInstance(参数1,参数2,参数3):其三个参数分别代表:

    • 用哪个类加载器去加载代理对象,即ProxyInvocationHandler类

    • 动态代理的类需要实现的接口,即service接口

    • 动态代理方法在执行时,会调用h里面的invoke方法去执行(在这个例子里就是this,实际上是ProxyInvocationHandler类中的invoke()方法)

  • this:代表的就是本类

  • getClass():返回值是类

  • getClassLoader():返回类的加载器

  • getInterfaces():返回类的接口

  • invoke(Object arg0, Method arg1, Object[] arg2):

    • arg0:就是代理对象,也就是target

    • arg1:调用的方法

    • arg3:方法中的参数

  • arg1.invoke(Object obj,Object args[])的作用就是调用arg1类代表的方法,其中obj是接口名,args调用的obj中的方法的,也就是说其返回的是obj接口中的args方法(用了反射,就是Method arg1.invoke())。就是使代理类在拥有userserviceimp中的所有方法的同时也能增加方法。

  • arg1.getName():调用方法的名字

    4.测试

    package com.fbw.agent;
    
    public class test1 {
    	public static void main(String[] args) {
    		//真实角色
    		userserviceimp u=new userserviceimp();
    		//生成代理类的工具,代理角色现在不存在
    		ProxyInvocationHandler pih=new ProxyInvocationHandler();
    		//真实角色已经实现了接口,代理角色也要实现接口,使将要生成的代理类也实现接口,现在其也代理了这个接口,并有了真实角色的方法
    		pih.setTarget(u);
    		//用接口强转,动态生成代理类,接口是连接真实角色和代理工具的桥梁
    		userservice p=(userservice) pih.getproxy();
    		p.add();
    	}
    
    }

流程:先new真实角色和代理工具,然后调用代理工具中的setTaget(u)方法把实现userservice接口的类的对象传入(使代理对象实现接口),代理类对象的getproxy()方法会返回生成代理对象,而这个代理对象在生成时会调用invoke()方法,这个invoke()方法会使代理类对象拥有userserviceimp中的所有方法,也能使其拥有userserviceimp,中没有的方法如本例的log()方法。

5.AOP

aop是面向切面的编程,其实它和代理很像,都是要过第三方类在不改变源代码的情况下完成需求。

目前流行的是Spring AOP和AspectJ,Spring AOP使用的是纯java实现,不需要专门的编译过程和类的加载器,在运行期间通过代理方式向目标类织入增强代码。

AspectJ是基于java语言的AOP框架,AspectJ扩展了java语言,提供了专门的编译器,并在编译时提供了横向代码的织入。

spring有五种通知方法:

  • Around 环绕通知 org.aopalliance.intercept.MethodInterceptor 拦截对目标方法调用,可用于日志、事务管理等功能

  • Before 前置通知 org.springframework.aop.MethodBeforeAdvice 在目标方法调用前调用,可用于权限管理等功能

  • After 后置通知 org.springframework.aop.AfterReturningAdvice 在目标方法调用后调用,可用于关闭流,上传文件,删除临时文件等功能

  • Throws 异常通知 org.springframework.aop.ThrowsAdvice 当目标方法抛出异常时调用,可以应用于处理异常记录日志等功能

  • 引介通知 org.springframework.aop.IntroductionInterceptor 在目标类中添加一些新的方法和属性,可以应用于修改老版本程序

    以下例子都是围绕这五个通知来进行

1.使用Spring的API接口

1)首先先建立userservice接口

package com.fbw.aop;

public interface userservice {
	void add();
	void delete();
	void update();
	void quary();
}

2)建立serviceimp类来实现接口

package com.fbw.aop;

public class userserviceimp implements userservice {

	public void add() {
		// TODO Auto-generated method stub
System.out.println("add a user");
	}

	public void delete() {
		// TODO Auto-generated method stub
System.out.println("delete a user");
	}

	public void update() {
		// TODO Auto-generated method stub
System.out.println("update a user");
	}

	public void quary() {
		// TODO Auto-generated method stub
System.out.println("quary a user");
	}

}

3)建立两个类(类都要继承通知类)来验证(本例子用的是前置通知和后置通知):

package com.fbw.aop;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class log implements MethodBeforeAdvice {
	//arg0:要执行的目标对象的方法
	//arg1:参数
	//arg2:目标对象
	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
		// TODO Auto-generated method stub
        //输出哪个包下的方法被执行
		System.out.println(arg2.getClass().getName()+"的"+arg0.getName()+"被执行了");
	}

}


package com.fbw.aop;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

public class afterlog implements AfterReturningAdvice {

	//arg0:返回值
	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
        //输出执行的方法和返回值
		System.out.println(arg1.getName()+"方法被执行了,返回结果为:"+arg0);
	}

}

4)配置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-4.3.xsd
	                       http://www.springframework.org/schema/aop
	                    http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
	                    
	                    
	                    
	       <!--注册bean  -->
			<bean id="ui" class="com.fbw.aop.userserviceimp"></bean>
			<bean id="log" class="com.fbw.aop.log"></bean>
			<bean id="afterlog" class="com.fbw.aop.afterlog"></bean>
				
			<!--方式一:使用Spring API接口  -->
			<!--配置aop  -->
			 <aop:config>
			<!-- 切入点:expression:表达式,execution(要执行的位置)  -->
			<aop:pointcut expression="execution(* com.fbw.aop.userserviceimp.*(..))" id="pointcut"/>
			<!-- 执行环绕  advice-ref里是要执行的类名-->
			<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
			<aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>
			</aop:config>
</beans>

5)测试

package com.fbw.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {
	public static void main(String[] args) {
		ApplicationContext app=new ClassPathXmlApplicationContext("aop.xml");
		userservice u=(userservice)app.getBean("ui");
		u.add();
	}

}

2.使用自定义类

1)JoinPoint 对象

JoinPoint对象封装了SpringAop中切面方法的信息,在切面方法中添加JoinPoint参数,就可以获取到封装了该方法信息的JoinPoint对象. 常用api:

方法名功能
Signature getSignature();获取封装了署名信息的对象,在该对象中可以获取到目标方法名,所属类的Class等信息
Object[] getArgs();获取传入目标方法的参数对象
Object getTarget();获取被代理的对象
Object getThis();获取代理对象

2)ProceedingJoinPoint对象

ProceedingJoinPoint对象是JoinPoint的子接口,该对象只用在@Around的切面方法中, 其中添加了 Object proceed() throws Throwable //执行目标方法 Object proceed(Object[] var1) throws Throwable //传入的新的参数去执行目标方法 两个方法.

1)定义一个div类用来构造5种通知的方法

package com.fbw.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class div {
	//前置通知
void before(JoinPoint joinpoint) {
	System.out.println("前置通知:模拟执行权限检查。。。。");
	System.out.println("目标类是:"+joinpoint.getTarget());
	System.out.println("被植入增强处理的目标方法是:"+joinpoint.getSignature().getName());
	
}
//后置通知
void after(JoinPoint joinpoint) {
	System.out.println("后置通知:模拟记录日志。。。。");
	System.out.println("被植入增强处理的目标方法为:"+joinpoint.getSignature().getName());
}

//环绕通知
	/*
	 * ProceedingJoinPoint是JoinPoint的一个子接口,表示可执行的目标方法 其必须是object类型的返回值
	 */
Object round(ProceedingJoinPoint proceedingjoinpoint) throws Throwable {
	System.out.println("环绕开始:执行目标之前,模拟开启事务");
	//执行当前目标方法
	Object obj=proceedingjoinpoint.proceed();
	System.out.println("环绕结束:执行目标方法之后,模拟关闭事务");
	return obj;
}
//异常通知
void yc(JoinPoint joinpoint,Throwable e) {
	System.out.println("出现了异常,异常信息是:"+e.getMessage());
}

//最终通知
void fianlnotice() {
	System.out.println("通知:结束了!!!");
}
}

2)设置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-4.3.xsd
	                       http://www.springframework.org/schema/aop
	                    http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
	                    
	                    
	                    
	       <!--注册bean  -->
			<bean id="ui" class="com.fbw.aop.userserviceimp"></bean>
			<bean id="diy" class="com.fbw.aop.div"></bean>
			<aop:config>
			<!-- 自定义切面。ref 要引入的类  -->
			<aop:aspect ref="diy">
			<!-- 切入点 ,expression中是要增强的方法 -->
			<aop:pointcut expression="execution(* com.fbw.aop.userserviceimp.*(..))" id="point"/>
		<!-- 	通知  -->
			<aop:before method="before" pointcut-ref="point"/>
			<aop:after-returning method="after" pointcut-ref="point" returning="returnval"/>
			<aop:around method="round" pointcut-ref="point"/>
			<aop:after-throwing method="yc" pointcut-ref="point" throwing="e"/>
			<aop:after method="fianlnotice" pointcut-ref="point"/>
			</aop:aspect>
			</aop:config>
</beans>

3)测试

package com.fbw.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {
	public static void main(String[] args) {
		ApplicationContext app=new ClassPathXmlApplicationContext("aop.xml");
		userservice u=(userservice)app.getBean("ui");
		u.add();
	}

}

3.使用注解

1)创建一个使用注解的类

package com.fbw.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class a {
	@Pointcut("execution(* com.fbw.aop.userserviceimp.*(..))")//相当于切入点,需要一个空的方法
	public void my() {
		
	}
	@Before("my()")
		//前置通知
	void before(JoinPoint joinpoint) {
		System.out.println("前置通知:模拟执行权限检查。。。。");
		System.out.println("目标类是:"+joinpoint.getTarget());
		System.out.println("被植入增强处理的目标方法是:"+joinpoint.getSignature().getName());
		
	}
	@AfterReturning("my()")
	//后置通知
	void after(JoinPoint joinpoint) {
		System.out.println("后置通知:模拟记录日志。。。。");
		System.out.println("被植入增强处理的目标方法为:"+joinpoint.getSignature().getName());
	}

	//环绕通知
		/*
		 * ProceedingJoinPoint是JoinPoint的一个子接口,表示可执行的目标方法 其必须是object类型的返回值
		 */
	@Around("my()")
	Object round(ProceedingJoinPoint proceedingjoinpoint) throws Throwable {
		System.out.println("环绕开始:执行目标之前,模拟开启事务");
		//执行当前目标方法
		Object obj=proceedingjoinpoint.proceed();
		System.out.println("环绕结束:执行目标方法之后,模拟关闭事务");
		return obj;
	}
	@AfterThrowing(value = "my()",throwing = "e")
	//异常通知
	void yc(JoinPoint joinpoint,Throwable e) {
		System.out.println("出现了异常,异常信息是:"+e.getMessage());
	}

	//最终通知
	@After("my()")
	void fianlnotice() {
		System.out.println("通知:结束了!!!");
	}
	}

2)配置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"
	   xmlns:context="http://www.springframework.org/schema/context"                     
	   xsi:schemaLocation="http://www.springframework.org/schema/beans     
                           http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
	                       http://www.springframework.org/schema/aop
	                    http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
	                    http://www.springframework.org/schema/context
	                    http://www.springframework.org/schema/context/spring-context-4.3.xsd">
	                    <!--也可以在userservice类中使用@component注解  -->
	                    <bean id="ui" class="com.fbw.aop.userserviceimp"></bean>
	                    <context:component-scan base-package="com.fbw.aop">
	                    </context:component-scan>
	                    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

3)测试运行

package com.fbw.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {
	public static void main(String[] args) {
		/*
		 * ApplicationContext app=new ClassPathXmlApplicationContext("aop.xml");
		 * userservice u=(userservice)app.getBean("ui"); u.add();
		 */
		ApplicationContext app=new ClassPathXmlApplicationContext("a.xml");
		userservice u=(userservice)app.getBean("ui");
		u.add();
	}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值