(1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值..)(2)使用注解,注解作用在类上面,方法上面,属性上面(3)使用注解目的:简化 xml 配置(1)@Component(2)@Service(3)@Controller(4)@Repository上面四个注解功能是一样的,都可以用来创建 bean 实例
(1)需要aop 依赖的支持 spring-aop
(2)开启组件扫描:1. 如果扫描多个包,多个包使用逗号隔开;2.扫描包上层目录
<?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:p="http://www.springframework.org/schema/p"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描-->
<context:component-scan base-package="com.qf"></context:component-scan>
</beans>
(3)创建类 在类上添加创建bean 的注解(在注解里面 value 属性值可以省略不写;默认值是类名称,首字母小写;UserService -- userService)
(4)开启组件扫描细节配置
<!--扫描该包下 的所有注解-->
<context:component-scan base-package="com.qf" />
(5)基于注解的方式 实现属性注入:
(1)@Autowired:先根据类型注入 再根据名字注入
第一步 把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解
第二步 在 service 注入 dao 对象,在 service 类添加 dao 类型属性,在属性上面使用注解
@Service
public class UserService {
//定义 dao 类型属性
//不需要添加 set 方法
//添加注入属性注解
@Autowired
private UserDao userDao;
public void add() {
System.out.println("service add.......");
userDao.add();
}
}
(2)@Qualifier:根据名称进行注入
这个@Qualifier 注解的使用,和上面@Autowired 一起使用
//定义 dao 类型属性
//不需要添加 set 方法
//添加注入属性注解
@Autowired //根据类型进行注入
@Qualifier(value = "userDaoImpl1")
//根据名称进行注入
private UserDao userDao;
(3)@Resource:先根据名字注入 再根据类型注入
//@Resource //根据类型进行注入
@Resource(name = "userDaoImpl1") //根据名称进行注入
private UserDao userDao;
(4)@Value:注入普通类型属性
@Value(value = "abc")
private String name;
(6)完全注解开发:
@Configuration //作为配置类,替代 xml 配置文件
@ComponentScan(basePackages = {"com.qf"})
public class SpringConfig {
}
用于替换自建类型组件的
(1)@Service 业务类专用 @Repository dao实现类专用 @Controller web层专用
(2)@Component 通用
(3)@Scope 用户控制bean的创建模式
// @Service说明 此类是一个业务类,需要将此类纳入工厂 等价替换掉
// @Service默认beanId == 首字母小写的类名"userServiceImpl"
// @Service("userService") 自定义beanId为"userService"
@Service //声明bean,且id="userServiceImpl"
@Scope("singleton") //声明创建模式,默认为单例模式 ;@Scope("prototype")即可设置为多例模式
public class UserServiceImpl implements UserService {
...
}
用于完成bean中属性值的注入:
(1)@Autowired 基于类型自动注入 先根据类型注入 如果找到多个 再根据名称注入
(2)@Resource 基于名称自动注入 先根据名称注入 如果根据名称没找到 则根据类型找 根据类型 找到多个 则报错 找到一个则注入
(3)@Qualifier("userDAO") 限定要自动注入的bean的id,一般和@Autowired联用
(4)@Value 注入简单类型数据 (jdk8种+String)
@Service
public class UserServiceImpl implements UserService {
@Autowired //注入类型为UserDAO的bean
@Qualifier("userDAO2") //如果有多个类型为UserDAO的bean,可以用此注解从中挑选一个
private UserDAO userDAO;
}
@Service
public class UserServiceImpl implements UserService {
@Resource("userDAO3") //注入id=“userDAO3”的bean
private UserDAO userDAO;
/*
@Resource //注入id=“userDAO”的bean
private UserDAO userDAO;
*/
}
public class XX{
@Value("100") //注入数字
private Integer id;
@Value("shine") //注入String
private String name;
}
用于控制事务切入:
(1)@Transactional
(2)工厂配置中的
//类中的每个方法都切入事务(有自己的事务控制的方法除外)
@Transactional(isolation=Isolation.READ_COMMITTED,propagation=Propagation.REQUIRED,readOnly=false,rollbackFor=Exception.class,timeout = -1)
public class UserServiceImpl implements UserService {
//该方法自己的事务控制,仅对此方法有效
@Transactional(propagation=Propagation.SUPPORTS)
public List<User> queryAll() {
return userDao.queryAll();
}
public void save(User user){
userDao.save(user);
}
}
(3)注解所需配置:
<!-- 告知spring,哪些包中 有被注解的类、方法、属性 -->
<!-- <context:component-scan base-package="com.qf.a,com.xx.b"></context:component-scan> -->
<context:component-scan base-package="com.qf"></context:component-scan>
<!-- 告知spring,@Transactional在定制事务时,基于txManager=DataSourceTransactionManager -->
<tx:annotation-driven transaction-manager="txManager"/>
(1)注解使用:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect // 声明此类是一个切面类:会包含切入点(pointcut)和通知(advice)
@Component //声明组件,进入工厂
public class MyAspect {
// 定义切入点
@Pointcut("execution(* com.qf.spring.service.UserServiceImpl.*(..))")
public void pc(){}
@Before("pc()") // 前置通知
public void mybefore(JoinPoint a) {
System.out.println("target:"+a.getTarget());
System.out.println("args:"+a.getArgs());
System.out.println("method's name:"+a.getSignature().getName());
System.out.println("before```~");
}
@AfterReturning(value="pc()",returning="ret") // 后置通知
public void myAfterReturning(JoinPoint a,Object ret){
System.out.println("after```~:"+ret);
}
@Around("pc()") // 环绕通知
public Object myAround(ProceedingJoinPoint p) throws Throwable {
System.out.println("interceptor1```~");
Object ret = p.proceed();
System.out.println("interceptor2```~");
return ret;
}
@AfterThrowing(value="pc()",throwing="ex") // 异常通知
public void myThrows(JoinPoint jp,Exception ex){
System.out.println("throws");
System.out.println("===="+ex.getMessage());
}
}
(2) 配置:
<!-- 添加如下配置,启用aop注解 -->
<aop:aspectj-autoproxy />
完结撒花,愿天下没有难写的代码,愿每一位程序员少走弯路!