1. 程式人生 > 實用技巧 >Spring-ioc註解程式設計

Spring-ioc註解程式設計

這裡的註解是最初級的一些註解,掌握了之後再學習其它的註解

註解掃描

<?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 https://www.springframework.org/schema/context/spring-context.xsd">
    
<!--此標籤表示開啟註解掃描,即掃描對應包及其子包的註解-->    
<context:component-scan base-package="com.ty"></context:component-scan>
</beans>

除了上述方式還可以指定過濾規則來進行註解掃描

<context:component-scan base-package="com.ty">
<!--排除過濾,排除包中的某些類
    type="":指定過濾規則
    	annotation:按照註解進行排除,標註了指定註解的元件不要,expression表示要過濾的註解
        assignable:指定排除某個具體的類,按照類排除,expression表示不註冊的具體類名
        aspectj:後面講aop的時候說明要使用的aspectj表示式,不用
        custom:定義一個typeFilter,自己寫程式碼決定哪些類被過濾掉,不用
        regex:使用正則表示式過濾,不用
    -->
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--包含過濾,指定包中的類
	需要先配置use-default-filters屬性,讓預設掃描方式失效,預設是掃描全部
	剩下的過濾屬性跟排除過濾相同
-->
<context:component-scan base-package="com.ty" use-default-filters="false">
   <context:include-filter type="aspectj" expression="com.ty.other.*"/>
</context:component-scan>

建立物件

@Component

此註解就是原配置方式中的<bean>標籤,即:<bean id="user" class="com.ty.bean.User">

註解中元件的id預設是類名首字母小寫,class就是底層通過反射獲取User類資訊;通過@Component分別又衍生出三個註解

@Controller:控制器,推薦給controller層新增此註解

@Service:業務邏輯,推薦給業務邏輯層新增此註解

@Repository:倉庫管理,推薦給資料訪問層新增此註解

這4個註解產生的效果方式是相同的,只是為了方便閱讀,提高可讀性

@Component
public class User {
    private String username;
    private String password;
    
    /*省略構造,getter/setter和toString方法 */
}

@Scope

設定bean物件的作用域,就是bean標籤中的scope屬性

@Lazy

延遲建立單例項物件,就是bean標籤中的lazy="false"屬性

@PostConstruct

@PreDestroy

這兩個註解表示bean物件的物件的生命週期,就是bean標籤中的init-method和destroy-method屬性

@PostConstruct
public void init() {
    System.out.println("init");
}

@PreDestroy
public void destroy() {
    System.out.println("destroy");
}

依賴注入

@Autowired

@Repository
public class UserDaoImpl implements UserDao {
    @Override
    public void findUser() {
        System.out.println("查詢使用者!");
    }
}
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Override
    public void login() {
        userDao.findUser();
    }
}

注意:此註解預設是按照型別進行自動裝配(就是注入)

1、如果只找到一個,則直接進行賦值,

2、如果沒有找到,則直接丟擲異常,

3、如果找到多個,那麼會按照變數名作為id繼續匹配,

​ 1、匹配上直接進行裝配

​ 2、如果匹配不上則直接報異常

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao2;

    @Override
    public void login() {
        userDao2.findUser();
    }
}

//UserServiceImpl2繼承UserServiceImpl類
@Service
public class UserServiceImpl2 extends UserServiceImpl {
    @Autowired
    private UserDao userDao;

    @Override
    public void login() {
        System.out.println("UserServiceImpl2");
        userDao.findUser();
    }
}
@Controller
public class UserController {
    @Autowired
    private UserService userServiceImpl;

    public void test() {
        userServiceImpl.login();
    }
}

方法上也可以有@Autowired註解

@Autowired
public void setUserService(UserService userServiceImpl) {
    this.userService = userServiceImpl;
}
@Qualifier

此註解配套@Autowired使用,用來指定id的名字,讓其按照名字裝配;按照名字找到了就進行裝配,否則就報錯

@Controller
public class UserController {
    @Autowired
    @Qualifier("userServiceImpl")
    private UserService userService;

    public void test() {
        userService.login();
    }
}

@Autowired註解可以用在方法上,@Qualifier只可以用在引數列表中

@Autowired
public void test(@Qualifier("userServiceImpl2") UserService userService) {
    System.out.println("此方法被呼叫:" + userService);
}

ps:方法上有@AutoWired註解時:bean建立時會自動呼叫,這個方法的每個引數都會自動注入

​ @Qualifier註解作用在引數上時,指定屬性的id名字

@Resource

@Resource註解的作用和@Autowired的作用相同,而且@Resource(name="") = @Autowired+@Resource

public class UserController {
    @Resource(name = "userServiceImpl")
    private UserService userService;
}

等同於:
public class UserController {
    @Autowired
    @Qualifier("userServiceImpl")
    private UserService userService;
}

兩者的功能相同,但還是有區別的:

@Autowired註解是Spring提供的,而@Resource是JavaEE規範提供的

​@Autowired註解預設按照型別裝配,而@Resource註解預設是按照名字裝配

@Value

屬性賦值,這種方式不能用在靜態變數上,而且不能注入集合型別

#先定義一個properties屬性檔案,並設定要注入屬性的值
username=jack
password=root
<!--把剛剛定義好的properties屬性檔案載入到配置檔案中-->
<context:property-placeholder location="classpath:bean.properties"></context:property-placeholder>

或者在類上新增@PropertySource("bean.properties")註解
//在屬性上加 @Value("${key}") 註解
@Value("${username}")
private String username;
@Value("${password}")
private String password;

最後再看一下泛型依賴

泛型依賴

public class Student {
}

public class Teacher {
}

public interface BaseDao<T> {
	void save();
}

//StudentDao.java
@Repository
public class StudentDao implements BaseDao<Student> {
    @Override
    public void save() {
        System.out.println("儲存學生!");
    }
}

//TeacherDao.java
@Repository
public class TeacherDao implements BaseDao<Teacher> {
    @Override
    public void save() {
        System.out.println("儲存老師!");
    }
}
public class BaseService<T> {
    @Autowired
    private BaseDao<T> baseDao;

    public void save(){
        baseDao.save();
    }
}

//StudentService.java
@Service
public class StudentService extends BaseService<Student> {
}

//TeacherService.java
@Service
public class TeacherService extends BaseService<Teacher> {
}
//測試
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
StudentService studentService = context.getBean("studentService", StudentService.class);
TeacherService teacherService = context.getBean("teacherService", TeacherService.class);
studentService.save();
teacherService.save();