1.声明Bean注释72
Bean的注释通常包括四种:
●@Component
●@Controller
●@Service
●@Repository
1.1源代码如下:1.1.1@Component注释
package com.powernode.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(value = {ElementType.TYPE})@Retention(value = RetentionPolicy.RUNTIME)public @interface Component { String value();}
1.1.2@Controller注释
package org.springframework.stereotype;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.core.annotation.AliasFor;@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface Controller { @AliasFor( annotation = Component.class ) String value() default "";}
1.1.3@Service注释
package org.springframework.stereotype;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.core.annotation.AliasFor;@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface Service { @AliasFor( annotation = Component.class ) String value() default "";}
1.1.4@Repository注释
package org.springframework.stereotype;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.core.annotation.AliasFor;@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface Repository { @AliasFor( annotation = Component.class ) String value() default "";}
1.2可以通过源码看到
@Controller、@Service、@Repository这三个注释都是@component注释的别名。
也就是说,这四个注释的功能是一样的。你可以用任何东西。
建议提高程序的可读性:
●使用控制器类:Controller
●使用service类:Service
●使用dao类:Repository
他们只有一个value属性。value属性用于指定bean的id,即bean的名称。
2.Spring注释使用73如何使用上述注释?
●第一步:依赖加入aop
●第二步:在配置文件中添加context命名空间
●第三步:在配置文件中指定扫描的包
●第四步:在Bean类中使用注释
第一步:依赖加入aop
我们可以看到,当加入spring-context依赖时,就会与加入aop的依赖有关。所以这一步不用做。
第二步:在配置文件中添加context命名空间
<?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: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/context http://www.springframework.org/schema/context/spring-context.xsd"></beans>
第三步:在配置文件中指定要扫描的包
<?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: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/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--指定Spring框架扫描哪些类别?--> <context:component-scan base-package="com.powernode.spring6.bean"/></beans>
第四步:在Bean类中使用注释
package com.powernode.spring6.bean;import org.springframework.stereotype.Component;///使用Spring注释 73@Component("userBean")public class User {}
package com.powernode.spring6.bean;import org.springframework.stereotype.Controller;/** * 使用Spring注释 73 **/@Controller("vipBean") // 如果属性名是value,这个属性名可以省略。public class Vip {}
package com.powernode.spring6.bean;import org.springframework.stereotype.Service;/** * 使用Spring注释 73 **/@Service("orderBean") // 假如你省略了整个value属性,bean有默认的名字吗?有:类名首字母变小写是bean的名字。有:类名首字母变小写是bean的名字。public class Order {}
package com.powernode.spring6.bean;import org.springframework.stereotype.Repository;/** * 使用Spring注释 73 **/@Repository("studentBean")public class Student {}
测试
///使用Spring注释 73 @Test public void testBeanComponent(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); User userBean = applicationContext.getBean("userBean", User.class); System.out.println(userBean); Vip vipBean = applicationContext.getBean("vipBean", Vip.class); System.out.println(vipBean); 我们不给value值///order类和Student类,使用默认值 // 如果你省略了整个value属性,bean有默认的名字吗?有:类名首字母变小写是bean的名字。 //Order orderBean = applicationContext.getBean("orderBean", Order.class); Order orderBean = applicationContext.getBean("order", Order.class); System.out.println(orderBean); //Student studentBean = applicationContext.getBean("studentBean", Student.class); Student studentBean = applicationContext.getBean("student", Student.class); System.out.println(studentBean);// OrderService orderService = applicationContext.getBean("orderService", OrderService.class);// System.out.println(orderService);//// OrderDao orderDao = applicationContext.getBean("orderDao", OrderDao.class);// System.out.println(orderDao); }
3.解决多包扫描问题743.1如果是多包怎么办?有两种解决方案:743.1.一是在配置文件中指定多个包,用逗号隔开。
com.powernode.spring6包下有两个包,一个是bean,一个是daoo
package com.powernode.spring6.dao;import org.springframework.stereotype.Component;/** * 使用Spring注释 73 **/@Componentpublic class OrderDao {}
<!--多个包,用逗号隔开。--> <context:component-scan base-package="com.powernode.spring6.bean,com.powernode.spring6.dao"/>
OrderDao orderDao = applicationContext.getBean("orderDao", OrderDao.class); System.out.println(orderDao);
3.1.二是指定多个包的共同父包。74
com.powernode.spring6包下有两个包,一个是bean,一个是daoo
package com.powernode.spring6.dao;import org.springframework.stereotype.Component;/** * 使用Spring注释 73 **/@Componentpublic class OrderDao {}
<!--多个包,也可以指定这多个包的共同父包,但这必须牺牲部分效率。--> <context:component-scan base-package="com.powernode.spring6>
///解决多包问题 74 OrderDao orderDao = applicationContext.getBean("orderDao", OrderDao.class); System.out.println(orderDao);
4.选择性实例化Bean755
假设一个包下有很多Bean,有的Bean上标有Component,有的标有Controler,有的标有Service,有的标有Repository。现在,由于某些特殊业务的需要,只允许所有Controler参与Bean管理,其他都不例外。我该怎么办?
use-default-filters="true“表示:使用Spring默认规则,只要有Component、Controller、Service、Repository中的任何注释标记都是实例化的。
use-default-filters="false“说:即使有Componenentt,也不再有spring默认的实例化规则、Controller、Service、Repository这些注释标签,也不再实例化。
说明只有Controller实例化。
<!-- 第一种解决方案: 75 use-default-filters="false" 假如这个属性是false,表示com.powernode.spring6.bean2包下的所有带 声明Bean的注释全部失效。@Component @Controller @Service @Repository全部失效。 --> <context:component-scan base-package="com.powernode.spring6.bean2" use-default-filters="false"> <!--只有@Repository @Service 包含在内,生效。--> <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> </context:component-scan>
use也可以使用-default-filters设置为true(不写就是true),用exclude-filter排出哪些注释标记的bean不参与实例化:
<!-- 第二种解决方案: 75 use-default-filters="true" 如果这个属性的值是true,则表示com.powernode.spring6.Bean2下的所有带有声明Bean的注释都生效了。 use-default-filters="true" 默认值是true,不用写。 --> <context:component-scan base-package="com.powernode.spring6.bean2"> <!--@controller注释失败--> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
package com.powernode.spring6.bean2;import org.springframework.stereotype.Component;import org.springframework.stereotype.Controller;import org.springframework.stereotype.Repository;import org.springframework.stereotype.Service;/** * Bean选择性实例化 75 **/@Componentpublic class A { public A() { System.out.println(执行A的无参数结构方法); }}@Controllerclass B { public B() { System.out.println(实施B无参数结构方法); }}@Serviceclass C { public C() { System.out.println(实施C的无参数结构方法); }}@Repositoryclass D { public D() { System.out.println(执行D的无参数结构方法); }}@Controllerclass E { public E() { System.out.println(执行E的无参数结构方法); }}
//选择性实例化Beann 75 @Test public void testChoose(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-choose.xml"); }