Spring注解开发

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:

  • (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 {
     	...   
    }
    

注入(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)工厂配置中的

    //类中的每个方法都切入事务(有自己的事务控制的方法除外)
    @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 />
    

完结撒花,愿天下没有难写的代码,愿每一位程序员少走弯路!

你可能感兴趣的:(学习随笔,spring,java,spring,boot)