注解
导包
配置文件添加
xmlns:context="http://www.springframework.org/schema/context"
<!--
指定扫描 com.company.annotations 包及所有子孙包下的所有类中的注解
-->
<context:component-scan base-package="com.company.annotations"></context:component-scan>
package com.company.annotations;
import com.company.bean.Car;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
//相当于<bean name="user2" class="com.company.bean.User"></bean>
//四种注解无区别,用于区分识别对象属于哪一层
//@Component("user2")
//@Service("user2") //service层
//@Controller("user2") //web层
@Repository("user2") //dao层
@Scope(scopeName = "prototype")
public class User2 {
//@Value("tom")
private String name;
private Integer age;
private Car2 car2;
public String getName() {
return name;
}
/**
* 两种
* 1.放在成员变量: 通过反射的Field赋值
* 2.放在setName方法: 通过set方法赋值
*/
@Value("tom")
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
@Value("18")
public void setAge(Integer age) {
this.age = age;
}
public Car2 getCar2() {
return car2;
}
/**
* 对象注入
*
* @Autowired
* @Qualifier("car2") 上两个组合使用或者直接使用 @Resource(name = "car2")
*/
//@Autowired
//@Qualifier("car2")
@Resource(name = "car2")
public void setCar2(Car2 car2) {
this.car2 = car2;
}
@PostConstruct
public void init() {
}
@PreDestroy
public void destory() {
}
}
spring aop
导包
准备目标对象
package com.company.aop;
public class UserServiceImpl implements UserService {
@Override
public void save() {
}
@Override
public void delete() {
}
@Override
public void update() {
}
@Override
public void find() {
}
}
准备通知
package com.company.aop;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAdvice {
//前置通知
public void before() {
System.out.println("这是前置通知");
}
//后置通知
public void afterReturning() {
System.out.println("这是后置通知(如果出现异常不会调用)");
}
//环绕通知
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("这是环绕通知之前的部分");
Object proceed = proceedingJoinPoint.proceed();//调用目标方法
System.out.println("这是环绕通知之后的部分");
return proceed;
}
//异常拦截通知
public void afterException() {
System.out.println("出现异常");
}
//后置通知
public void after() {
System.out.println("这是后置通知(如果出现异常也会调用)");
}
}
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
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--导入 xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation 添加 http://www.springframework.org/schema/aop/spring-aop.xsd
-->
<!--配置目标对象-->
<bean name="userService" class="com.company.aop.UserServiceImpl"></bean>
<!--配置通知对象-->
<bean name="myAdvice" class="com.company.aop.MyAdvice"></bean>
<!--配置将通知织入目标对象-->
<aop:config>
<!-- 配置切入点
public void com.company.aop.UserServiceImpl.save()
void com.company.aop.UserServiceImpl.save()
* com.company.aop.UserServiceImpl.save()
* com.company.aop.UserServiceImpl.*()
* com.company.aop.UserServiceImpl.*(..)
* com.company.aop.*ServiceImpl.*(..)
* com.company.aop..*ServiceImpl.*(..)
-->
<aop:pointcut id="pc" expression="execution(* com.company.aop.*ServiceImpl.*(..))"></aop:pointcut>
<aop:aspect ref="myAdvice">
<!--指定名为before的方法作为前置通知-->
<aop:before method="before" pointcut-ref="pc"></aop:before>
<aop:after-returning method="afterReturning" pointcut-ref="pc"></aop:after-returning>
<aop:around method="around" pointcut-ref="pc"></aop:around>
<aop:after-throwing method="afterException" pointcut-ref="pc"></aop:after-throwing>
<aop:after method="after" pointcut-ref="pc"></aop:after>
</aop:aspect>
</aop:config>
</beans>
错误提示:Caused by: org.xml.sax.SAXParseException; lineNumber: 21; columnNumber: 17; cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 'aop:config' 的声明。
添加 xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
测试
package com.company.aop;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:com/company/aop/applicationContext.xml")
public class Demo {
@Resource(name = "userService")
private UserService userService;
@Test
public void func() {
userService.save();
}
}
输出
注解配置
<?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
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置目标对象-->
<bean name="userService" class="com.company.aop.UserServiceImpl"></bean>
<!--配置通知对象-->
<bean name="myAdvice" class="com.company.aop.MyAdvice"></bean>
<!--配置将通知织入目标对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
package com.company.aop2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
//表示该类为通知类
@Aspect
public class MyAdvice {
@Pointcut("execution(* com.company.aop.*ServiceImpl.*(..))")
public void pc() {
}
//前置通知
@Before("MyAdvice.pc()")
public void before() {
System.out.println("这是前置通知");
}
//后置通知
@AfterReturning("MyAdvice.pc()")
public void afterReturning() {
System.out.println("这是后置通知(如果出现异常不会调用)");
}
//环绕通知
@Around("MyAdvice.pc()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("这是环绕通知之前的部分");
Object proceed = proceedingJoinPoint.proceed();//调用目标方法
System.out.println("这是环绕通知之后的部分");
return proceed;
}
//异常拦截通知
@AfterThrowing("MyAdvice.pc()")
public void afterException() {
System.out.println("出现异常");
}
//后置通知
@After("MyAdvice.pc()")
public void after() {
System.out.println("这是后置通知(如果出现异常也会调用)");
}
}