Springboot注解 @Bean、@Component、 @Service、 @Repository 、@Controller、@Autowired @Qualifier @Primary

@Bean、@Component、 @Service、 @Repository 、 @Controller

@Bean:表示一个方法实例化、配置或者初始化一个Spring IoC容器管理的新对象。

@Data
@EnableConfigurationProperties
@Configuration
@ConfigurationProperties(prefix = "redis.cache")
public class RedisCacheConfig {
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        return new RedisCacheManager(
                RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
                this.getRedisCacheConfigurationWithTtl(600),
                this.getRedisCacheConfigurationMap()
        );
    }
}

@Component: 自动被component扫描。 表示被注解的类会自动被component扫描

@Component

public class RedisLimiterUtils {
    @Resource
    RedisTemplate<Object, Object> redisTemplate;
    @Resource(name = "stringRedisTemplate")
    ValueOperations<String, String> ops;
    @Resource(name = "redisTemplate")
    ValueOperations<Object, Object> objOps;

public void saveObject(String key, Object obj, long timeout) {
        redisUtil.set(key, obj, timeout);
    }


    public void saveObject(String key, Object obj) {
        redisUtil.set(key, obj);
    }


    public Object getObject(String key) {
        return redisUtil.get(key);
    }


    public void removeObject(String key) {
        redisUtil.del(key);
    }
}

@Repository: 用于持久层,主要是数据库存储库。

@Repository
public interface NginxLogDao extends ElasticsearchRepository<NinxLogDocument, String> {

}

@Service: 表示被注解的类是位于业务层的业务component。

@Slf4j
@Service
public class ValidateCodeServiceImpl implements ValidateCodeService {

@Autowired
  private RedisTemplate<String, Object> redisTemplate;

  /**
   * 保存用户验证码,和randomStr绑定
   * @param deviceId
   *            客户端生成
   * @param imageCode
   *            验证码信息
   */
  @Override
  public void saveImageCode(String deviceId, String imageCode) {
      String text = imageCode.toLowerCase().toString();
      redisTemplate.execute(new RedisCallback<String>() {
          @Override
          public String doInRedis(RedisConnection connection) throws DataAccessException {
              // redis info
              connection.set(buildKey(deviceId).getBytes(), imageCode.getBytes());
              connection.expire(buildKey(deviceId).getBytes(), 60*5);
              connection.close();
              return "";
          }
      });

  }

  /**
   * 获取验证码
   * @param deviceId
   *            前端唯一标识/手机号
   */
  @Override
  public String getCode(String deviceId)  {
      String code = "" ;
      try {
          code = redisTemplate.execute(new RedisCallback<String>() {
              @Override
              public String doInRedis(RedisConnection connection) throws DataAccessException {
                  // redis info
                  byte[] temp = "".getBytes();
                  temp = connection.get(buildKey(deviceId).getBytes()) ;
                  connection.close();
                  return new String(temp);
              }
          });
      } catch (Exception e) {
          throw new AuthenticationException("验证码不存在"){};
      }
      return code ;
  }

  /**
   * 删除验证码
   * @param deviceId
   *            前端唯一标识/手机号
   */
  @Override
  public void remove(String deviceId) {
      redisTemplate.execute(new RedisCallback<String>() {
          @Override
          public String doInRedis(RedisConnection connection) throws DataAccessException {
              // redis info
              connection.del(buildKey(deviceId).getBytes());
              connection.close();
              return "";
          }
      });
  }

  /**
   * 验证验证码
   */
  @Override
  public void validate(HttpServletRequest request) {
      String deviceId = request.getParameter("deviceId");
      if (StringUtils.isBlank(deviceId)) {
          throw new AuthenticationException("请在请求参数中携带deviceId参数"){};
      }
      String code = this.getCode(deviceId);
      String codeInRequest;
      try {
          codeInRequest = ServletRequestUtils.getStringParameter(request, "validCode");
      } catch (ServletRequestBindingException e) {
          throw new AuthenticationException ("获取验证码的值失败"){};
      }
      if (StringUtils.isBlank(codeInRequest)) {
          throw new AuthenticationException ("请填写验证码"){};
      }

      if (code == null) {
          throw new AuthenticationException ("验证码不存在或已过期"){};
      }

      if (!StringUtils.equalsIgnoreCase(code, codeInRequest)) {
          throw new AuthenticationException ("验证码不正确"){};
      }
      this.remove(deviceId);
  }

  private String buildKey(String deviceId) {
      return "DEFAULT_CODE_KEY:" + deviceId;
  }
}

@Controller:表明被注解的类是控制component,主要用于展现层 。

@Controller
@Api(tags = "REDIS API")
@RequestMapping("/redis")
public class RedisController {
   @Autowired
    private RedisTemplate<String,Object> redisTemplate ;
 @ResponseBody
    @RequestMapping("/memoryInfo")
    @LogAnnotation(module="auth-server",recordRequestParam=false)
    public String getMemoryInfo() {
        Map<String, Object> map = new HashMap<>();
        Object o = redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.info("memory").get("used_memory");
            }
        });
        map.put("used_memory", o);
        map.put("create_time", System.currentTimeMillis());
        return JSON.toJSONString(map);
    }
}

@Bean与@Component区别
@Component是 spring 2.5引入的,为了摆脱通过classpath扫描根据xml方式定义的bean的方式.

@Bean是spring 3.0 引入的,和 @Configuration一起工作,为了摆脱原先的xml和java config方式。

Spring管理Bean方式有两种,一种是注册Bean,一种装配Bean。
可以通过三种方式实现bean管理,一使用自动配置的方式、二使用JavaConfig的方式、三使用XML配置的方式。

@Component
@Data
public class User{
    private String name = "tom";
}
@Bean 需要在配置类中使用,即类上需要加上@Component或者@Configuration注解, 通常加上@Configuration@Bean的用法在这里。

@Configuration
public class AppConfig {

    @Bean
    public TransferServiceImpl transferService() {
        return new TransferServiceImpl();
    }
}

@Autowired
private TransferService transferService;

@Component与@Service区别
目前基本没有区别。@Service是一种具体的@Component

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
   String value() default "";
}

@Autowired
自动装配

@Component("fooFormatter")
    public class FooFormatter implements Formatter {
        public String format() {
            return "foo";
        }
    }

    @Component("barFormatter")
    public class BarFormatter implements Formatter {
        public String format() {
            return "bar";
        }
    }

    @Component
    public class FooService {
        @Autowired
        private Formatter formatter;
        
        //todo 
    }

上面的例子会抛出异常NoUniqueBeanDefinitionException,用@Qualifier注解指定

@Component
    public class FooService {
        @Autowired
        @Qualifier("fooFormatter")
        private Formatter formatter;
        //todo 
    }

也可以在 Formatter 实现类上使用 @Qualifier 注释,而不是在 @Component 或者 @Bean 中指定名称,也能达到相同的效果

@Component
     @Qualifier("fooFormatter")
     public class FooFormatter implements Formatter {
         public String format() {
             return "foo";
         }
     }
 
     @Component
     @Qualifier("barFormatter")
     public class BarFormatter implements Formatter {
         public String format() {
             return "bar";
         }
     }

@Primary 指定默认注入的bean消除歧义

@Component
     @Primary
     public class FooFormatter implements Formatter {
         public String format() {
             return "foo";
         }
     }

     @Component
     public class BarFormatter implements Formatter {
         public String format() {
             return "bar";
         }
     }

@Compent 作用就相当于 XML配置

@Component
@Data
public class User{
    private String name = "tom";
}

备注:
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type。

Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。

如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。

作者:学无止境吧
链接:https://www.jianshu.com/p/e7a62409f682
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 11
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
@Bean注解和@Component注解都是Spring框架用来标识一个类为Bean的注解,它们有一些共同点和区别。 共同点: 1. 标识Bean:无论是@Bean注解还是@Component注解,它们都可以用来标识一个类为Spring容器Bean。 2. 自动注册:被@Bean注解或@Component注解标识的类会被Spring容器扫描并注册为Bean,可以在其他地方通过@Autowired注解进行注入。 3. 依赖注入:无论是@Bean注解还是@Component注解,它们都可以用于依赖注入,即在其他Bean通过@Autowired注解引用。 区别: 1. 使用方式:@Bean注解通常用于Java配置方式,即通过@Configuration注解的类来进行配置;而@Component注解是通用的注解,可以用于任何场景,包括Java配置方式和XML配置方式。 2. 方法级别 vs 类级别:@Bean注解通常用于方法上,表示将方法返回的对象注册为Bean;而@Component注解通常用于类级别,表示将整个类注册为Bean。但是,在使用@Component注解时,也可以用于方法上,效果与@Bean注解类似。 3. 细分注解:@Component注解还有一些派生注解,如@Service、@Repository、@Controller等,用于标识不同类型的Bean。这些派生注解在功能上与@Component注解是一样的,只是为了更好地区分和组织不同类型的Bean。 4. 参数注入:@Bean注解的方法可以接受参数,这些参数可以是其他的Bean,也可以是普通的Java对象;而@Component注解的类不能直接接受参数,需要使用构造函数或setter方法来进行注入。 总的来说,@Bean注解适用于Java配置方式,主要用于方法级别的Bean注册;@Component注解适用于通用的Bean注册场景,主要用于类级别的Bean注册,并且还有一些派生注解用于标识不同类型的Bean。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值