Spring 入门 简单工厂 实例:学生学习课程
创建课程工厂、课程接口
1 2 3 4 5 6 package top.eshyee.newinstance;public interface ICourse { public void learn () ; }
1 2 3 4 5 6 7 8 package top.eshyee.newinstance;public class JavaCourse implements ICourse { @Override public void learn () { System.out.println("java课程" ); } }
1 2 3 4 5 6 7 8 9 package top.eshyee.newinstance;public class HtmlCourse implements ICourse { @Override public void learn () { System.out.println("html课程" ); } }
课程工厂
1 2 3 4 5 6 7 8 9 10 11 package top.shyee.factory;import top.eshyee.newinstance.HtmlCourse;import top.eshyee.newinstance.ICourse;import top.eshyee.newinstance.JavaCourse;public class CourseFactory { public static ICourse getCourse (String name) { return name.equals("java" ) ? new JavaCourse () : name.equals("html" )?new HtmlCourse ():null ; } }
学生类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 package top.eshyee.entity;import top.eshyee.newinstance.HtmlCourse;import top.eshyee.newinstance.ICourse;import top.eshyee.newinstance.JavaCourse;import top.shyee.factory.CourseFactory;public class Student { private int stuNo; private String stuName; private int stuAge; public int getStuNo () { return stuNo; } public void setStuNo (int stuNo) { this .stuNo = stuNo; } public String getStuName () { return stuName; } public void setStuName (String stuName) { this .stuName = stuName; } public int getStuAge () { return stuAge; } public void setStuAge (int stuAge) { this .stuAge = stuAge; } @Override public String toString () { return "Student [stuNo=" + stuNo + ", stuName=" + stuName + ", stuAge=" + stuAge + "]" ; } public void learn (String name) { ICourse course1=CourseFactory.getCourse(name); course1.learn(); } }
测试
public class Test1 { public static void main(String[] args) { StudentlearnwithFactory(); }
1 2 3 4 5 6 7 8 public class Test1 { public static void main (String[] args) { StudentlearnwithFactory(); } public static void StudentlearnwithFactory () { Student student = new Student (); student.learn("java" ); }}
测试结果:java课程
IOC 超级工厂,可以放各种对象。控制反转,也成为DI(依赖注入)
使用IOC实现以上操作
配置XML–添加三个bean
1 2 3 4 5 6 7 <bean id ="student" class ="top.eshyee.entity.Student" > <property name ="stuNo" value ="1" > </property > <property name ="stuAge" value ="2" > </property > <property name ="stuName" value ="genge" > </property > </bean > <bean id ="JavaCourse" class ="top.eshyee.newinstance.JavaCourse" > </bean > <bean id ="HtmlCourse" class ="top.eshyee.newinstance.HtmlCourse" > </bean >
重写学生的learn方法
1 2 3 4 5 public void learn (String name) { ApplicationContext context = new ClassPathXmlApplicationContext ("applicationContext.xml" ); ICourse course = (ICourse)context.getBean(name); course.learn(); }
写个测试方法
1 2 3 4 5 public static void StudentlearnwithIOC () { ApplicationContext context = new ClassPathXmlApplicationContext ("applicationContext.xml" ); Student student = (Student) context.getBean("student" ); student.learn("JavaCourse" ); }
运行结果:java课程
依赖注入(DI) set注入 property
创建teacher和course类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package top.eshyee.entity;public class Teacher {private String name;private int age;public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } @Override public String toString () { return "Teacher [name=" + name + ", age=" + age + "]" ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package top.eshyee.entity;public class Course {private String courseName;private int courseHour;private Teacher teacher;public String getCourseName () { return courseName; } public void setCourseName (String courseName) { this .courseName = courseName; } public int getCourseHour () { return courseHour; } public void setCourseHour (int courseHour) { this .courseHour = courseHour; } public Teacher getTeacher () { return teacher; } public void setTeacher (Teacher teacher) { this .teacher = teacher; } @Override public String toString () { return "Course [courseName=" + courseName + ", courseHour=" + courseHour + ", teacher=" + teacher + "]" ; } }
加入到IOC中
1 2 3 4 5 6 7 8 9 <bean id ="teacher" class ="top.eshyee.entity.Teacher" > <property name ="name" value ="Shyee" > </property > <property name ="age" value ="12" > </property > </bean > <bean id ="course" class ="top.eshyee.entity.Course" > <property name ="courseName" value ="JAVA" > </property > <property name ="courseHour" value ="13" > </property > <property name ="teacher" ref ="teacher" > </property > </bean >
写一个测试类
1 2 3 4 5 6 public static void testDI () { ApplicationContext context = new ClassPathXmlApplicationContext ("applicationContext.xml" ); Teacher teacher = (Teacher) context.getBean("teacher" ); Course course = (Course) context.getBean("course" ); System.out.println(course); }
运行结果:Course [courseName=JAVA, courseHour=13, teacher=Teacher [name=Shyee, age=12]]
赋值默认是set方法
构造方法注入 constructor
修改xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <bean id ="teacher" class ="top.eshyee.entity.Teacher" > <constructor-arg value ="Shyeee" > </constructor-arg > <constructor-arg value ="15" > </constructor-arg > </bean > <bean id ="course" class ="top.eshyee.entity.Course" > <constructor-arg value ="PYTHON" > </constructor-arg > <constructor-arg value ="15" > </constructor-arg > <constructor-arg ref ="teacher" > </constructor-arg > </bean >
加入构造方法
Course
1 2 3 4 5 6 7 8 9 public Course (String courseName, int courseHour, Teacher teacher) { super (); this .courseName = courseName; this .courseHour = courseHour; this .teacher = teacher; } public Course () { super (); }
Teacher
1 2 3 4 5 6 7 8 9 public Teacher (String name, int age) { super (); this .name = name; this .age = age; } public Teacher () { super (); }
运行结果:Course [courseName=PYTHON, courseHour=15, teacher=Teacher [name=Shyeee, age=15]]
P命名空间 xmlns:p="http://www.springframework.org/schema/p"
1 2 3 4 5 6 7 8 <?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:p ="http://www.springframework.org/schema/p" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > <bean id ="teacher" class ="top.eshyee.entity.Teacher" p:name ="Shyeeee" p:age ="14" > </bean > <bean id ="course" class ="top.eshyee.entity.Course" p:courseName ="ORACLE" p:courseHour ="1" p:teacher-ref ="teacher" > </bean > </beans >
运行结果:Course [courseName=ORACLE, courseHour=1, teacher=Teacher [name=Shyeeee, age=14]]
各种类型的注入 Arrays&List&Map&Properties&Set 创建包含各种类型的类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 package top.eshyee.entity;import java.util.Arrays;import java.util.List;import java.util.Map;import java.util.Properties;import java.util.Set;public class AllcollectionType {private List<String> list;private String[] array;private Set<String> set;private Map<String, String> map;private Properties properties;public List<String> getList () { return list; } public void setList (List<String> list) { this .list = list; } public String[] getArray() { return array; } public void setArray (String[] array) { this .array = array; } public Set<String> getSet () { return set; } public void setSet (Set<String> set) { this .set = set; } public Map<String, String> getMap () { return map; } public void setMap (Map<String, String> map) { this .map = map; } public Properties getProperties () { return properties; } public void setProperties (Properties properties) { this .properties = properties; } @Override public String toString () { String ss="" ; for (String s:array) { ss=ss+s+"," ; } ss="[" +ss+"]" ; return "AllcollectionType [list=" + list + "\n array=" + ss + "\n set=" + set + "\n map=" + map + "\n properties=" + properties + "]" ; } }
注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 <bean id ="collectionType" class ="top.eshyee.entity.AllcollectionType" > <property name ="array" > <array > <value > I</value > <value > A</value > <value > M</value > </array > </property > <property name ="list" > <list > <value > S</value > <value > H</value > <value > Y</value > <value > E</value > <value > E</value > </list > </property > <property name ="map" > <map > <entry > <key > <value > NI</value > </key > <value > ni</value > </entry > <entry > <key > <value > C</value > </key > <value > c</value > </entry > <entry > <key > <value > E</value > </key > <value > e</value > </entry > </map > </property > <property name ="properties" > <props > <prop key ="TO" > to</prop > <prop key ="ME" > me</prop > <prop key ="ET" > et</prop > </props > </property > <property name ="set" > <set > <value > Y</value > <value > O</value > <value > U</value > </set > </property > </bean >
set和array都可以用list标签,相反也可,但是建议用相应标签
测试
1 2 3 4 5 public static void testcollectionType () { ApplicationContext context = new ClassPathXmlApplicationContext ("applicationContext.xml" ); AllcollectionType a = (AllcollectionType) context.getBean("collectionType" ); System.out.println(a); }
运行结果
AllcollectionType [list=[S, H, Y, E, E] array=[I,A,M,] set=[Y, O, U] map={NI=ni, C=c, E=e} properties={ME=me, TO=to, ET=et}]
null和空字符串 1 2 3 4 5 6 7 8 9 10 11 <bean id ="student1" class ="top.eshyee.entity.Student" > <property name ="stuNo" > <null /> </property > <property name ="stuName" > <value > </value > </property > </bean >
自动装配 autowire="byName"
会自动找一个id为teacher 的bean,只有对象之间的依赖关系可以自动装配
1 2 3 4 5 6 7 8 9 <bean id ="teacher" class ="top.eshyee.entity.Teacher" > <property name ="name" value ="Shyee" > </property > <property name ="age" value ="12" > </property > </bean > <bean id ="course" class ="top.eshyee.entity.Course" autowire ="byName" > <property name ="courseName" value ="JAVA" > </property > <property name ="courseHour" value ="13" > </property > </bean >
运行结果:Course [courseName=JAVA, courseHour=13, teacher=Teacher [name=Shyee, age=12]]
autowire="byType"
按类型自动装配,寻找一个teacher类型的bean,但是有两个teacher会报错。
expected single matching bean but found 2: teacher1,teacher2
autowire="constructor"
适用于构造方法中有多个依赖
添加全局的autowire–default-autowire="byName"
1 2 3 4 5 6 <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:p ="http://www.springframework.org/schema/p" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire ="byName" >
注解 配置扫描器
1 2 3 4 5 6 7 8 9 10 <?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:p ="http://www.springframework.org/schema/p" default-autowire ="byName" xmlns:context ="http://www.springframework.org/schema/context" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd" ><context:component-scan base-package ="top.eshyee.dao" > </context:component-scan > </beans >
用注解声明一个bean
相当于在xml中的<bean id="stuentDao" class="top.eshyee.dao.StuentDaoImpl"></bean>
1 2 3 4 5 6 7 8 9 10 package top.eshyee.dao;import org.springframework.stereotype.Component;import top.eshyee.entity.Student;@Component("StuentDao") public class StuentDaoImpl { public void addStudent (Student student) { System.out.println("增加学生" ); } }
dao层注解:@Repository
service层注解:@Service
控制器层注解:@Controller
使用注解实现事务 需要使用到spring-tx-4.3.9.RELEASE.jar
、ojdbc.jar
、commons-dbcp.jar
、commons-pool.jar
、spring-jdbc-4.3.9.RELEASE.jar
、aopalliance.jar
配置xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <bean id ="dataSource" class ="org.apache.commons.dbcp.BasicDataSource" > <property name ="driverClassName" value ="oracle.jdbc.driver" > </property > <property name ="url" value ="127.0.0.1:1521:ORCL" > </property > <property name ="username" value ="SCOTT" > </property > <property name ="password" value ="tiger" > </property > <property name ="maxActive" value ="10" > </property > <property name ="maxIdle" value ="6" > </property > </bean > <bean id ="txManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name ="dataSource" ref ="dataSource" > </property > </bean > <tx:annotation-driven transaction-manager ="txManager" />
创建DAO层及实现类
1 2 3 4 5 6 7 package top.eshyee.dao;import top.eshyee.entity.Student;public interface IStudentDao { public void addStudent (Student student) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 package top.eshyee.dao.impl;import org.springframework.stereotype.Repository;import top.eshyee.dao.IStudentDao;import top.eshyee.entity.Student;@Repository("StuentDao") public class StudentDaoImpl implements IStudentDao { public void addStudent (Student student) { System.out.println("增加学生" ); } }
创建service层及实现类
1 2 3 4 5 6 7 package top.eshyee.service;import top.eshyee.entity.Student;public interface IStudentService { void addStudent (Student student) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package top.eshyee.service.impl;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import top.eshyee.dao.IStudentDao;import top.eshyee.entity.Student;import top.eshyee.service.IStudentService;public class StudentServiceImpl implements IStudentService { IStudentDao studentDao ; @Transactional(readOnly = false ,propagation = Propagation.REQUIRED) @Override public void addStudent (Student student) { studentDao.addStudent(student); } public IStudentDao getStudentDao () { return studentDao; } public void setStudentDao (IStudentDao studentDao) { this .studentDao = studentDao; } }
注入到IOC
1 2 3 4 5 <bean id ="studentDao" class ="top.eshyee.dao.impl.StudentDaoImpl" > </bean > <bean id ="studentService" class ="top.eshyee.service.impl.StudentServiceImpl" > <property name ="studentDao" ref ="studentDao" > </property > </bean >
AOP 面向方面编程
前置通知 每当执行add之前自动执行的方法
准备jar
aopalliance.jar
、aspectjweaver-1.5.3.jar
编写前置通知
1 2 3 4 5 6 7 8 9 10 package top.eshyee.aop;import java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;public class LogBefore implements MethodBeforeAdvice { @Override public void before (Method method, Object[] args, Object target) throws Throwable { System.out.println("前置通知" ); } }
配置前置通知
1 2 3 4 5 6 7 8 <bean id ="logBefore" class ="top.eshyee.aop.LogBefore" > </bean > <aop:config > <aop:pointcut expression ="execution(public void top.eshyee.service.impl.StudentServiceImpl.addStudent(top.eshyee.entity.Student))" id ="pointcut" /> <aop:advisor advice-ref ="logBefore" pointcut-ref ="pointcut" /> </aop:config >
测试
1 2 3 4 5 public static void testAOP () { ApplicationContext context = new ClassPathXmlApplicationContext ("applicationContext.xml" ); IStudentService studentService= (IStudentService) context.getBean("studentService" ); Student student=getStudent1(); studentService.addStudent(student);
运行结果:
前置通知 增加学生
expression=“execution(…)” 的常见写法
举例
含义
public boolean addStudent(org.lanqiao.entity.Student))
所有返回类型为boolean、参数类型为org.lanqiao.entity.Student的addStudent()方法。
public boolean org.lanqiao.service.IStudentService. addStudent(org.lanqiao.entity.Student)
org.lanqiao.service.IStudentService类(或接口)中的addStudent()方法,并且返回类型是boolean、参数类型是org.lanqiao.entity.Student
public * addStudent(org.lanqiao.entity.Student)
“*”代表任意返回类型
public void *( org.lanqiao.entity.Student)
“*”代表任意方法名
public void addStudent(..)
“..”代表任意参数列表
* org.lanqiao.service.. (..)
org.lanqiao.service.IStudentService包中,包含的所有方法(不包含子包中的方法)
* org.lanqiao.service... (..)
org.lanqiao.service.IStudentService包中,包含的所有方法(包含子包中的方法)
后置通知 service层添加一个新业务 void deleteStudentByno(int stuNo);
添加实现方法
1 2 3 4 @Override public void deleteStudentByno (int stuNo) { System.out.println("删除学生" ); }
编写AOP
1 2 3 4 5 6 7 8 9 package top.eshyee.aop;import java.lang.reflect.Method;import org.springframework.aop.AfterReturningAdvice;public class LogAfter implements AfterReturningAdvice { @Override public void afterReturning (Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("后置通知,目标对象:" +target+",调用的方法名:" +method.getName()+",调用的参数个数:" +args.length+",方法的返回值:" +returnValue); } }
注入IOC
1 2 3 4 5 6 7 8 <bean id ="logAfter" class ="top.eshyee.aop.LogAfter" > </bean > <aop:config > <aop:pointcut expression ="execution(public void top.eshyee.service.impl.StudentServiceImpl.addStudent(top.eshyee.entity.Student)) or execution(public void top.eshyee.service.impl.StudentServiceImpl.deleteStudentByno(int))" id ="pointcut" /> <aop:advisor advice-ref ="logBefore" pointcut-ref ="pointcut" /> <aop:advisor advice-ref ="logAfter" pointcut-ref ="pointcut" /> </aop:config >
运行结果:
前置通知 增加学生 后置通知,目标对象:top.eshyee.service.impl.StudentServiceImpl@5b1ebf56,调用的方法名:addStudent,调用的参数个数:1,方法的返回值:null 前置通知 删除学生 后置通知,目标对象:top.eshyee.service.impl.StudentServiceImpl@5b1ebf56,调用的方法名:deleteStudentByno,调用的参数个数:1,方法的返回值:null
异常通知 源码注释中:Implementing classes must implement methods of the form: void afterThrowing([Method, args, target], ThrowableSubclass);
及必须实现以上方法
编写AOP
1 2 3 4 5 6 7 8 9 package top.eshyee.aop;import java.lang.reflect.Method;import org.springframework.aop.ThrowsAdvice;public class LogException implements ThrowsAdvice { public void afterThrowing (Method method, Object[] args,Object target, Throwable ex) { System.out.println("异常通知,目标对象:" +target+",调用方法:" +method.getName()+",参数个数:" +args.length+",异常原因:" +ex.getMessage()); } }
注入IOC
1 2 3 4 5 6 7 8 9 <bean id ="logException" class ="top.eshyee.aop.LogException" > </bean > <aop:config > <aop:pointcut expression ="execution(public void top.eshyee.service.impl.StudentServiceImpl.addStudent(top.eshyee.entity.Student)) or execution(public void top.eshyee.service.impl.StudentServiceImpl.deleteStudentByno(int))" id ="pointcut" /> <aop:advisor advice-ref ="logBefore" pointcut-ref ="pointcut" /> <aop:advisor advice-ref ="logAfter" pointcut-ref ="pointcut" /> <aop:advisor advice-ref ="logException" pointcut-ref ="pointcut" /> </aop:config >
搞点异常
1 2 3 4 5 @Override public void deleteStudentByno (int stuNo) { int a=1 /0 ; System.out.println("删除学生" ); }
运行结果:
前置通知 增加学生 后置通知,目标对象:top.eshyee.service.impl.StudentServiceImpl@16414e40,调用的方法名:addStudent,调用的参数个数:1,方法的返回值:null 前置通知 异常通知,目标对象:top.eshyee.service.impl.StudentServiceImpl@16414e40,调用方法:deleteStudentByno,参数个数:1,异常原因:/ by zeroException in thread "main" java.lang.ArithmeticException: / by zero
环绕通知 前后+异常
编写AOP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package top.eshyee.aop;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;public class LogAround implements MethodInterceptor { @Override public Object invoke (MethodInvocation invocation) throws Throwable { Object result = null ; try { System.out.println("环绕通知实现的前置通知" ); result = invocation.proceed(); System.out.println("环绕通知实现的后置通知,目标对象:" + invocation.getThis() + ",调用的方法名:" + invocation.getMethod().getName() + ",调用的参数个数:" + invocation.getArguments() + ",方法的返回值:" + result); } catch (Exception e) { System.out.println("环绕通知实现的异常通知" ); } return result; } }
注入IOC
1 2 3 4 5 6 7 8 9 10 <bean id ="logAround" class ="top.eshyee.aop.LogAround" > </bean > <aop:config > <aop:pointcut expression ="execution(public void top.eshyee.service.impl.StudentServiceImpl.addStudent(top.eshyee.entity.Student)) or execution(public void top.eshyee.service.impl.StudentServiceImpl.deleteStudentByno(int))" id ="pointcut" /> <aop:advisor advice-ref ="logBefore" pointcut-ref ="pointcut" /> <aop:advisor advice-ref ="logAfter" pointcut-ref ="pointcut" /> <aop:advisor advice-ref ="logException" pointcut-ref ="pointcut" /> <aop:advisor advice-ref ="logAround" pointcut-ref ="pointcut" /> </aop:config >
运行结果:
前置通知 环绕通知实现的前置通知 增加学生 环绕通知实现的后置通知,目标对象:top.eshyee.service.impl.StudentServiceImpl@46dffdc3,调用的方法名:addStudent,调用的参数个数:[Ljava.lang.Object;@5a709816,方法的返回值:null 后置通知,目标对象:top.eshyee.service.impl.StudentServiceImpl@46dffdc3,调用的方法名:addStudent,调用的参数个数:1,方法的返回值:null 前置通知 环绕通知实现的前置通知 删除学生 环绕通知实现的后置通知,目标对象:top.eshyee.service.impl.StudentServiceImpl@46dffdc3,调用的方法名:deleteStudentByno,调用的参数个数:[Ljava.lang.Object;@78383390,方法的返回值:null 后置通知,目标对象:top.eshyee.service.impl.StudentServiceImpl@46dffdc3,调用的方法名:deleteStudentByno,调用的参数个数:1,方法的返回值:null
使用注解实现AOP 在XML配置扫描器以及对AOP的支持
1 2 3 4 <aop:aspectj-autoproxy > </aop:aspectj-autoproxy > <context:component-scan base-package ="top.eshyee.aop" > </context:component-scan >
编写AOP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 package top.eshyee.aop;import java.util.Arrays;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.springframework.stereotype.Component;@Component("logAnnotation") @Aspect public class LogWithAnnotation { @Before("execution(public void top.eshyee.service.impl.StudentServiceImpl.addStudent(top.eshyee.entity.Student))") public void myBefore (JoinPoint jp) { System.out.println("注解形式--前置通知" ); } @AfterReturning(pointcut = "execution(public void top.eshyee.service.impl.StudentServiceImpl.addStudent(top.eshyee.entity.Student))", returning = "returningValue") public void myAfterReturning (JoinPoint jp, Object returningValue) { System.out.println("注解形式--后置通知,目标对象:" + jp.getTarget() + ",方法名:" + jp.getSignature() + ",参数列表:" + Arrays.toString(jp.getArgs()) + "返回值:" + returningValue); } @AfterThrowing(pointcut="execution(public void top.eshyee.service.impl.StudentServiceImpl.addStudent(top.eshyee.entity.Student))",throwing ="e") public void myException (JoinPoint jp,NullPointerException e) { System.out.println("注解形式--异常通知" ); } @Around("execution(public void top.eshyee.service.impl.StudentServiceImpl.addStudent(top.eshyee.entity.Student))") public void myAround (ProceedingJoinPoint pjp) { try { System.out.println("注解形式--环绕通知--前置通知" ); pjp.proceed(); System.out.println("注解形式--环绕通知--后置通知" ); } catch (Throwable e) { System.out.println("注解形式--环绕通知--异常通知" ); } finally { System.out.println("注解形式--环绕通知--最终通知" ); } } @After("execution(public void top.eshyee.service.impl.StudentServiceImpl.addStudent(top.eshyee.entity.Student))") public void myAfter () { System.out.println("注解形式--最终通知" ); } }
运行结果:
注解形式–环绕通知–前置通知 注解形式–前置通知 增加学生 注解形式–环绕通知–后置通知 注解形式–环绕通知–最终通知 注解形式–最终通知 注解形式–后置通知,目标对象:top.eshyee.service.impl.StudentServiceImpl@77b14724,方法名:void top.eshyee.service.IStudentService.addStudent(Student),参数列表:[Student [stuNo=0, stuName=genge, stuAge=0]]返回值:null 删除学生
基于SCHEMA配置 类似于实现接口的方式
编写AOP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package top.eshyee.aop;import java.util.Arrays;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;public class LogSchema { public void afterReturning (JoinPoint jp,Object returningValue) throws Throwable { System.out.println("Schema形式--后置通知,目标对象:" + jp.getTarget() + ",方法名:" + jp.getSignature() + ",参数列表:" + Arrays.toString(jp.getArgs()) + "返回值:" + returningValue); } public void before () throws Throwable { System.out.println("Schema后置通知" ); } public void myException (JoinPoint jp) { System.out.println("Schema异常通知" ); } public Object myAround (ProceedingJoinPoint pjp) { Object result=null ; try { System.out.println("Schema环绕前置通知" ); result=pjp.proceed(); System.out.println("Schema环绕后置通知" ); } catch (Throwable e) { System.out.println("Schema环绕异常通知" ); } return result; } }
注入IOC
1 2 3 4 5 6 7 8 9 10 11 12 13 <bean id ="logSchema" class ="top.eshyee.aop.LogSchema" > </bean > <aop:config > <aop:pointcut expression ="execution(public void top.eshyee.service.impl.StudentServiceImpl.addStudent(top.eshyee.entity.Student)) or execution(public void top.eshyee.service.impl.StudentServiceImpl.deleteStudentByno(int))" id ="pointcut2" /> <aop:aspect ref ="logSchema" > <aop:before method ="before" pointcut-ref ="pointcut2" /> <aop:after-returning method ="afterReturning" returning ="returningValue" pointcut-ref ="pointcut2" /> <aop:after-throwing method ="myException" pointcut-ref ="pointcut2" /> <aop:around method ="myAround" pointcut-ref ="pointcut2" /> </aop:aspect > </aop:config >
运行结果:
Schema后置通知 Schema环绕前置通知 注解形式–环绕通知–前置通知 注解形式–前置通知 增加学生 注解形式–后置通知,目标对象:top.eshyee.service.impl.StudentServiceImpl@31000e60,方法名:void top.eshyee.service.IStudentService.addStudent(Student),参数列表:[Student [stuNo=0, stuName=genge, stuAge=0]]返回值:null 注解形式–最终通知 注解形式–环绕通知–后置通知 注解形式–环绕通知–最终通知 Schema环绕后置通知 Schema形式–后置通知,目标对象:top.eshyee.service.impl.StudentServiceImpl@31000e60,方法名:void top.eshyee.service.IStudentService.addStudent(Student),参数列表:[Student [stuNo=0, stuName=genge, stuAge=0]]返回值:null Schema后置通知 Schema环绕前置通知 删除学生 Schema环绕后置通知 Schema形式–后置通知,目标对象:top.eshyee.service.impl.StudentServiceImpl@31000e60,方法名:void top.eshyee.service.IStudentService.deleteStudentByno(int),参数列表:[1]返回值:null