且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Spring IoC — 基于注解的配置

更新时间:2022-10-04 21:09:46

原文:Spring IoC — 基于注解的配置

基于XML的配置,Bean定义信息和Bean实现类本身是分离的,而采用基于注解的配置方式时,Bean定义信息即通过在Bean实现类上标注注解实现。

@Component:对类进行标注,Spring容器自动将POJO转换为容器管理的Bean;
@Repository:用于对DAO实现类进行标注;
@Service:用于对Service实现类进行标注;
@Controller:用于对Controller实现类进行标注。
 
1、自动装配Bean:
 
beans.xml:
<?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-3.0.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd"
         >
   <context:component-scan base-package="com.ioc.ch4_10"/>
   <bean id="ls" class="com.ioc.ch4_10.LogonService"></bean>
   <!-- context:component-scan base-package="com.baobaotao" resource-pattern="anno/*.class"/ -->
   <!-- context:component-scan base-package="com.baobaotao">
       <context:include-filter type="regex" expression="com\.baobaotao\.anno.*Dao"/>
       <context:include-filter type="regex" expression="com\.baobaotao\.anno.*Service"/>
       <context:exclude-filter type="aspectj" expression="com.baobaotao..*Controller+"/>
   </context:component-scan -->
</beans>

 LogDao类:

package com.ioc.ch4_10;
import org.springframework.stereotype.Component;
@Component("logDao")
public class LogDao {
}

UserDao_1类:

package com.ioc.ch4_10;
import org.springframework.stereotype.Component;
@Component("userDao_1")
//自动被Spring容器识别,Spring容器自动将POJO转换为容器管理的Bean
//等价于XML配置的<bean id="userDao_1" class="com.ioc.ch4_10.UserDao_1">
public class UserDao_1 {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "UserDao_1{" +
                "name='" + name + '\t' +
                '}';
    }
    public UserDao_1() {
        System.out.println("userDao");
    }
}

UserDao_2类:

package com.ioc.ch4_10;
import org.springframework.stereotype.Component;
/**
 * Created by gao on 16-3-25.
 */
@Component("userDao_2")
public class UserDao_2 {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "UserDao_2{" +
                "name='" + name + '\t' +
                '}';
    }
    public UserDao_2() {
        System.out.println("userDao_2");
    }
}

UserDao_3类:

package com.ioc.ch4_10;
import org.springframework.stereotype.Component;
/**
 * Created by gao on 16-3-25.
 */
@Component("userDao_3")
public class UserDao_3 {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "UserDao_3{" +
                "name='" + name + '\t' +
                '}';
    }
    public UserDao_3() {
        System.out.println("userDao_3");
    }
}

LogonService类:

package com.ioc.ch4_10;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class LogonService{
    //使用@Autowired进行自动注入
    @Autowired
    private LogDao logDao;
    @Autowired
    private UserDao_1 userDao1;
    //使用@Autowired的required属性,设置为false表示找不到匹配的Bean完成注入也不要抛出异常
    @Autowired(required = false)
    private UserDao_2 userDao_2;
    //使用@Qualifier指定注入Bean的名称
    @Autowired
    @Qualifier("userDao_3")
    private UserDao_3 userDao_3;
    public LogDao getLogDao() {
        return logDao;
    }
    public UserDao_1 getUserDao1() {
        return userDao1;
    }
    public UserDao_2 getUserDao2() {
        return userDao_2;
    }
    public UserDao_3 getUserDao3() {
        return userDao_3;
    }
    public void printSomething(){
        userDao1.setName("LogonService-userDao1");
        System.out.println(userDao1.toString());
        userDao_2.setName("LogonService-userDao2");
        System.out.println(userDao_2.toString());
        userDao_3.setName("LogonService-userDao3");
        System.out.println(userDao_3.toString());
    }
}

LoginService_2类:

package com.ioc.ch4_10;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
/**
 * Created by gao on 16-3-25.
 */
@Service
public class LogonService_2 {
    private LogDao logDao;
    private UserDao_1 userDao_1;
    //自动将LogDao传给方法入参
    @Autowired
    public void setLogDao(LogDao logDao) {
        System.out.println("auto setlogdao");
        this.logDao = logDao;
    }
    //自动将名为userDao的Bean传给方法入参
    @Autowired
    public void setUserDao_1(UserDao_1 userDao_1) {
        System.out.println("auto setuserdao");
        this.userDao_1 = userDao_1;
    }
    @Autowired
    public void init(@Qualifier("userDao_1")UserDao_1 userDao,LogDao logDao){
        System.out.println("multi param inject");
        this.userDao_1 = userDao;
        this.logDao =logDao;
    }
}

测试类:

package com.ioc.ch4_10;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * Created by gao on 16-3-25.
 */
public class Test {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com\\ioc\\ch4_10\\beans.xml");
        LogonService ls = (LogonService) ctx.getBean("ls");
        ls.printSomething();
    }
}

 

输出结果:
userDao
userDao_2
userDao_3
multi param inject
auto setlogdao
auto setuserdao
UserDao_1{name='LogonService??userDao1}
UserDao_2{name='LogonService-userDao2 }
UserDao_3{name='LogonService-userDao3 }
 
 
2、对集合类进行标注
Plugin接口:
package com.ioc.ch4_10;
public interface Plugin {
}

 onePlugin类:

package com.ioc.ch4_10;
import org.springframework.stereotype.Component;
@Component
public class OnePlugin implements Plugin {
}

twoPlugin类:

package com.ioc.ch4_10;
import org.springframework.stereotype.Component;
@Component
public class TwoPlugin implements Plugin {
}

MyComponent类:

package com.ioc.ch4_10;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class MyComponent {
    //Spring会将容器中所有类型为Plugin的Bean注入到这个变量中
    @Autowired(required=false)
    private List<Plugin> plugins;
    public List<Plugin> getPlugins() {
        return plugins;
    }
}

mycomponent.xml:

<?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-3.0.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:component-scan base-package="com.ioc.ch4_10">
        <context:include-filter type="aspectj" expression="com.baobaotao.anno.*Plugin+"/>
        <context:include-filter type="aspectj" expression="com.baobaotao.anno.MyComponent"/>
    </context:component-scan>
</beans>

MyComponentTest类:

package com.ioc.ch4_10;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyComponentTest {
    public static void main(String[] args) throws Throwable {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com\\ioc\\ch4_10\\mycomponent.xml");
        MyComponent myComponent = ctx.getBean(MyComponent.class);
        System.out.println("pulgin.size:"+myComponent.getPlugins().size());
        
    }
}
输出结果:
userDao
userDao_2
userDao_3
multi param inject
auto setlogdao
auto setuserdao
pulgin.size:2
 
3、Bean作用范围及生命过程方法
使用Scope指定作用范围
package com.ioc.ch4_10;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
//指定Bean的作用范围为prototype
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Component
public class Car {
    private int maxSpeed;
    public String brand;
    private double price;
    
    ......
}

 

 Boss类:

package com.ioc.ch4_10;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
@Component
public class Boss {
    
    private Car car;
    public Boss(){
        System.out.println("construct...");
    }
    @Resource
    private void setCar(Car car){
        System.out.println("execute in setCar");
        this.car = car;
    }
    
    @PostConstruct
    private void init1(){
        System.out.println("execute in init1");
    }
    
    @PostConstruct
    private void init2(){
        System.out.println("execute in init1");
    }
    
    @PreDestroy
    private void destory1(){
        System.out.println("execute in destory1");
    }
    
    @PreDestroy
    private void destory2(){
        System.out.println("execute in destory2");
    }
}

测试类:

package com.ioc.ch4_10;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * Created by gao on 16-3-25.
 */
public class Test {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com\\ioc\\ch4_10\\beans.xml");

        Car car1 = (Car) ctx.getBean("car");
        Car car2 = (Car) ctx.getBean("car");
        System.out.println(car1 == car2); //false
        UserDao_2 ud1 = (UserDao_2) ctx.getBean("userDao_2");
        UserDao_2 ud2 = (UserDao_2) ctx.getBean("userDao_2");
        System.out.println(ud1 == ud2); //true
        ((ClassPathXmlApplicationContext)ctx).destroy();
    }
}
输出结果:
construct...
execute in setCar
execute in init1
execute in init1
false
true
execute in destory2
execute in destory1