Spring注解开发
什么是注解
(1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值..)
(2)使用注解,注解作用在类上面,方法上面,属性上面
(3)使用注解目的:简化 xml 配置
Spring针对Bean管理创建对象提供的注解
(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 { }
声明Bean
用于替换自建类型组件的 <bean...>标签;可以更快速的声明bean:
-
(1)@Service 业务类专用 @Repository dao实现类专用 @Controller web层专用
-
(2)@Component 通用
-
(3)@Scope 用户控制bean的创建模式
// @Service说明 此类是一个业务类,需要将此类纳入工厂 等价替换掉 <bean class="xxx.UserServiceImpl"> // @Service默认beanId == 首字母小写的类名"userServiceImpl" // @Service("userService") 自定义beanId为"userService" @Service //声明bean,且id="userServiceImpl" @Scope("singleton") //声明创建模式,默认为单例模式 ;@Scope("prototype")即可设置为多例模式 public class UserServiceImpl implements UserService { ... }
注入(DI)
用于完成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)工厂配置中的 <tx:advice.... 和 <aop:config... 可以省略 !
//类中的每个方法都切入事务(有自己的事务控制的方法除外) @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"/>
AOP开发
-
(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 />
完结撒花,愿天下没有难写的代码,愿每一位程序员少走弯路!