一、IOC
1、配置文件实现IOC
IOC :控制反转,将创建对象的控制权又之前的new转移给Spring框架,目的是为了解耦。
- 导入相应的Jar包。
- 导入配置文件applicationContext.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:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <!-- 菜系类 --> <bean id="cuisine" class="com.bb.hrb.pojo.Cuisine"> <!-- <property name="name" value="鲁菜"></property>--> <constructor-arg index="0" value="东北菜"></constructor-arg> </bean> <!-- 菜品类 --> <bean id="food" class="com.bb.hrb.pojo.Food"> <!-- 通过setter方法进行依赖注入,直接引用上面的id为cuisine属性赋值 --> <!-- <property name="cuisine" ref="cuisine"></property>--> <!-- 通过构造器进行依赖注入 --> <constructor-arg index="0" value="猪肉炖粉条"></constructor-arg> <constructor-arg index="1" value="36.8"></constructor-arg> <constructor-arg index="2" ref="cuisine"></constructor-arg> </bean> </beans>
属性介绍:
<bean id="" class=""></bean> class属性是用来指明类的包名加类名,id属性用来获取这个bean对象 <bean id="" class=""> <property name="" ref=""></property> </bean> property标签用来通过setter方法进行依赖注入,name属性是bean对象中属性名,ref指向一个 bean的id,还可以有value属性,用于直接设置基本数据类型 <bean id="" class=""> <constructor-arg index="" value="" ref=""></constructor-arg> </bean> constructor-arg标签是通过构造器进行依赖注入,index属性指定第几个构造器参数0为第一个, value用于直接设置基本数据类型。ref指向一个bean的id
-
现在就可以直接使用了!实现如下:
// 读取配置文件,如果配置文件中bean中已经赋值,则返回一个赋好值得对象,反之则返回空对象
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//food为配置文件里的id
Food food = (Food) ac.getBean("food");
System.out.println(food);
2、注解实现IOC
使用注解只需要在Spring配置文件中添加标签:自动扫描注解
<context:component-scan base-package="com.bb.hrb"></context:component-scan>
1、bean注解
@Control 用于控制层组件
@Service 用于业务层组件
@Respository 用于DAO层组件
@Component 用于其它组件
以上注解使用后都可以创建bean对象,没有区别,不同的使用只是便于分层理解
添加注解之后默认将类名(首字母小写)定义为bean的id名,id也可以自己定义(注解后
添加小括号双引号,在其中添加自定义的id名)
2、依赖注入注解
@Resource JDK提供的
@AutoWired Spring提供的 默认按照类型匹配,也可指定id
@Qualifier 配合@AutoWired使用,用于指定注入的bean的id
二、AOP
1、配置文件实现AOP
AOP: "面向切面编程"或者叫做"面向方面编程"
可以动态的在一个类的方法执行前后自动之前其它类的方法,在不改变这两个类代码的前提下就可以实现,这种编程思想就是"面向切面编程",当不再需要使用时可以自由分开。
1、首先还是导入相应的jar包
2、模拟创建 两个类
UserService类
public class UserService{
public void addUser() {
System.out.println("用户注册");
}
public String deleteUser() {
System.out.println("删除用户");
String name = null;
try{
name.length();
} catch(Exception ex) {}
return "success";
}
}
UserLogging通知类
import org.aspectj.lang.ProceedingJoinPoint;
public class UserLogging {
public void logger() {
System.out.println("前置通知...");
}
public void afterLogger() {
System.out.println("最终通知...");
}
public void afterLoggerReturning(Object ret) {
System.out.println("后置通知..." + ", 返回值是:" + ret);
}
public void afterLoggerThrowing(Exception ex) {
System.out.println("异常通知...");
//ex.printStackTrace();
}
/*
* 环绕通知需要ProceedingJoinPoint执行proceed()目标方法
* 并且需要return执行proceed()后的返回值
*/
public Object aroundLogger(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知前部...");
Object r = pjp.proceed();// 执行目标方法
System.out.println("环绕通知后部...");
return r;
}
}
3、然后在Spring配置文件中加入
<bean id="userService" class="com.oracle.service.UserServiceImpl"></bean>
<bean id="logg" class="com.oracle.aop.UserLogging"></bean>
<aop:config>
<!-- 定义切入点 -->
<!-- 第一个*代表返回值,第二个*代表类,第三个*代表方法,(..)所有的重载方法,..表示任意的参数列表 -->
<aop:pointcut expression="execution(* com.oracle.service.*.*(..))" id="servicePointcut"/>
<!-- 配置切面 -->
<aop:aspect id="loggeraspect" ref="logg">
<!-- 前置通知 -->
<aop:before method="logger" pointcut-ref="servicePointcut"/>
<!-- 最终通知 -->
<aop:after method="afterLogger" pointcut-ref="servicePointcut"/>
<!-- 后置通知 returning="ret"的值要和异常通知的方法的参数一致 -->
<aop:after-returning method="afterLoggerReturning" pointcut-ref="servicePointcut" returning="ret"/>
<!-- 异常通知 throwing="ex"的值要和异常通知的方法的参数一致 -->
<aop:after-throwing method="afterLoggerThrowing" pointcut-ref="servicePointcut" throwing="ex"/>
<!-- 环绕通知 -->
<aop:around method="aroundLogger" pointcut-ref="servicePointcut"/>
</aop:aspect>
</aop:config>
4、大功告成,写一个测试类测试一下吧!
public class TestUserService {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService service = (UserService) ac.getBean("userService");
service.addUser();
String r = service.deleteUser();
System.out.println(r);
}
}
2、注解实现AOP
使用注解只需要在Spring配置文件中写两行
<!-- 注解IOC -->
<context:component-scan base-package="com.oracle"></context:component-scan>
<!-- 注解AOP -->
<aop:aspectj-autoproxy />
举个栗子:
我们把上面用配置文件实现的改一下
UserService类:
import org.springframework.stereotype.Service;
@Service("userService")
public class UserService {
public void addUser() {
System.out.println("用户注册");
}
public String deleteUser() {
System.out.println("删除用户");
String name = null;
try{
name.length();
} catch(Exception ex) {}
return "success";
}
}
UserLogging通知类:这里只拿前置通知为例
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class UserLogging {
// 定义切入点,这个方法就相当于切入点id
@Pointcut("execution(* com.oracle.service.*.*(..))")
public void servicePointcut(){}
@Before("servicePointcut()")
public void logger() {
System.out.println("前置通知...");
}
public void afterLogger() {
System.out.println("最终通知...");
}
public void afterLoggerReturning(Object ret) {
System.out.println("后置通知..." + ", 返回值是:" + ret);
}
public void afterLoggerThrowing(Exception ex) {
System.out.println("异常通知...");
//ex.printStackTrace();
}
/*
* 环绕通知需要ProceedingJoinPoint执行proceed()目标方法
* 并且需要return执行proceed()后的返回值
*/
public Object aroundLogger(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知前部...");
Object r = pjp.proceed();// 执行目标方法
System.out.println("环绕通知后部...");
return r;
}
}
好了可以测试一下了,测试类用上面的就可以。