浅谈spring 常用注解
|
我们不妨先将spring常用的注解按照功能进行分类 1 、将普通类加入容器形成Bean的注解 日常开发中主要使用到的定义Bean的注解包括(XML方式配置bean暂不讨论): @Component、@Repository、@Service、@Controller、@Bean 其中@Component、@Repository、@Service、@Controller实质上属于同一类注解,用法相同,功能相同,区别在于标识组件的类型。当一个组件代表数据访问层(Dao)时,你可以给它加上@Repository注解,如下例:
@Repository
public class BiliAPIDaoImpl implements BiliAPIDao {
private final static Logger LOGGER = LoggerFactory.getLogger(BiliAPIDaoImpl.class);
private BiliAPIHttpClient asoAPIHttpClient;
public void execute(){
//some logic business
}
}
当组件用于业务层时,使用@Service注解,如下例:
@Service(value="SecUserService")
public class SecUsersServiceImpl implements SecUsersService {
@Autowired
private SecUsersDao secUsersDao;
@Autowired
private SecRoleUserService secRoleUserService;
public void doBusiness(){
//do some business
}
}
注意,在此处的@Service注解中额外添加了value=”SecUserService”的属性,为何对此一举呢?value属性可以指定生成后Bean的名称,这个名称便成为容器中bean 的唯一标识符。同样的,在@Component、@Repository、@Controller也均可以指定其value值,当然,是如有必要时加 当组件属于控制层时,则使用@Controller注解;当组件不能进行很好地归类时,那我们可以使用@Component注解。因使用方式均相同,故此处不再继续贴代码 在这几个注解中,额外需要留意的是@Bean注解。不妨看代码:
@Component
public class FactoryMethodComponent {
private static int i;
@Bean @Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
// use of a custom qualifier and autowiring of method parameters
@Bean
protected TestBean protectedInstance(@Qualifier("public") TestBean spouse,@Value("#{privateInstance.age}") String country) {
TestBean tb = new TestBean("protectedInstance",1);
tb.setSpouse(tb);
tb.setCountry(country);
return tb;
}
@Bean @Scope(BeanDefinition.SCOPE_SINGLETON)
private TestBean privateInstance() {
return new TestBean("privateInstance",i++);
}
@Bean @Scope(value = WebApplicationContext.SCOPE_SESSION,proxyMode = ScopedProxyMode.TARGET_CLASS)
public TestBean requestScopedInstance() {
return new TestBean("requestScopedInstance",3);
}
}
Bean注解主要用于方法上,有点类似于工厂方法,当使用了@Bean注解,我们可以连续使用多种定义bean时用到的注解,譬如用@Qualifier注解定义工厂方法的名称,用@Scope注解定义该bean的作用域范围,譬如是singleton还是prototype等。 此处还得另外提一个注解: @Configuration.实际上,上面谈到的@Bean注解更多时候是与@Configuration注解在一起使用的。如果将一个类标注为@Configuration注解,那么也就意味着这个class将会作为创建各种bean的工厂(类似于一个新的容器)。最简单的配合使用示例如下:
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
以上的代码实际上等价于Xml中的配置: <beans> <bean class="com.acme.services.MyServiceImpl" id="myService"> </bean></beans> 我们还需要注意的一点,在Spring的@Component注解中使用@Bean与在Spring中的@Configuration使用是一定的差别的。在使用@Component的类中不会强制使用CGLIB代理拦截方法和属性。而在@Configuration类中,则会使用CGLIB代理去调用@Bean标注的方法并返回对象的引用。在@Configuration注解中使用@Bean也可以防止同一个@Bean方法被意外调用多次时而产生细微的难以排查的错误 2、从容器中取Bean(装配bean)时常用的注解 开发中最常用到的用于装配的注解是:@Autowired和@Resource @Autowired注解:
public class MovieRecommender {
@Autowired
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
@Autowired注解可用于为类的属性、构造器、方法进行注值。默认情况下,其依赖的对象必须存在(bean可用),如果需要改变这种默认方式,可以设置其required属性为false。另外一个比较重要的点就是,@Autowired注解默认按照类型装配,如果容器中包含多个同一类型的Bean,那么启动容器时会报找不到指定类型bean的异常,解决办法是结合@Qualified注解进行限定,指定注入的bean名称 @Resource注解
public class SpringAnotationDemo {
@Bean
@Qualifier("httpApiClient")
public HttpApiClient createHttpClient() {
return new HttpApiClient();
}
@Resource(name = "httpApiClient")
private HttpApiClient httpApiClient;
@Resource(type = XQSmsHttpClient.class)
private SmsHttpClient smsHttpClient;
}
依我个人理解,其实@Resource要比@Autowired好用得多,@Resource注解的使用性更为灵活,可指定名称,也可以指定类型 ,而用@Autowired注解进行装配容易抛出异常,特别是装配的bean类型有多个的时候,而解决的办法是需要在增加@Qualitied进行限定 vc模块注解">3、spring MVC模块注解 @Controller、@RequestMapping、@RequestParam、@PathVariable @Controller
@Controller
public class CompanyController {
/**this class will be the controller component of container**/
...
}
@RequestMapping
@Controller
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService;
...
}
如上例,当标注在class上时,表明此类会接收url为”/company”请求 @RequestParam
@Controller
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService;
@RequestMapping("/companyList")
public String listCompanies(Map<string,object=""> map,@RequestParam(value = "data",required = false) String data,@RequestParam(value = "phone_num",required = true) String phoneNum) {
map.put("data",data);
map.put("phoneNum",phoneNum);
return "companyList";
}
...
}
譬如上例中,@RequestParam请求参数指定了传入参数的具体字段名(value指定的),以及是否必须传的字段(默认情况下,required=true)。data,phoneNum为形参,即请求参数的使用名,可以更改 @PathVariable
@Controller
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService;
@RequestMapping("{companyName}")
public String getCompany(Map<string,@PathVariable String companyName) {
Company company = companyService.findByName(companyName);
map.put("company",company);
return "company";
}
...
}
当我们请求 “/compony/account”时,componyName会动态地绑定为”account” 4、事务模块注解@Transactional 在处理dao层或service层的事务操作时,譬如删除失败时的回滚操作,可用到@Transactional注解,如下例:
@Service
public class CompanyServiceImpl implements CompanyService {
@Autowired
private CompanyDAO companyDAO;
@Transactional(propagation = Propagation.REQUIRED,readOnly = false,rollbackFor = Exception.class)
public int deleteByName(String name) {
int result = companyDAO.deleteByName(name);
return company;
}
...
}
上例表明,执行deleteByName方法时,启用了事务处理,事务的各属性含义如下: propagation
注:第一种是最常用的,默认的 (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
